rust에서 cpp의 클래스를 이용하는 방법을 찾고 있다.
rust에서 autocxx
crate를 사용하면 된다.
#pragma once
#include <vector>
#include <string>
class Test {
public:
std::string name;
uint32_t horns;
// Test(const std::string& name, uint32_t horns) : name(name), horns(horns) {}
std::string get_name() {
return name;
}
void set_name(const std::string& name) {
this->name = name;
}
};
Test Class가 있다고 하자. rust에서 Test의 객체를 만들어서 사용하는 법을 알아보겠다.
[dependencies]
autocxx = "0.27.1"
cxx = "1.0.78"
[build-dependencies]
autocxx-build = "0.27.1"
cargo.toml
파일에 위와같이 의존성과 빌드 의존성을 추가해준다.
autocxx::include_cpp! {
#include "test_wrapper.h"
safety!(unsafe_ffi)
generate!("TestWrapper")
generate!("Test")
}
include_cpp!
매크로를 사용한다. #include
로 불러올 헤더파일을 인클루드 해준다.
기본적으로 include_cpp를 통해 생성된 c++ 코드는 unsafe
하다 즉, unsafe
코드 블록안에서 사용해야한다.
safety!
매크로를 include_cpp!
매크로 내부에 명시적으로 사용할 경우 compiler에게 c++코드가 안전하지 않다고 말해주는 것 과 같다.
generate
는 c++ 코드를 rust에서 호출할 수 있도록 바인딩된 코드를 생성해준다.
1. c++ 헤더 파일을 분석하여 클래스, 함수, 변수 등의 정보를 추출한다.
2. 추출된 정보를 바탕으로 rust에서 c++ 코드를 호출하기 위해 바인딩된 코드를 생성한다.
3. c++타입과 rust타입 간의 변환 코드를 생성한다.
Test
클래스를 객체화하여 사용하기 위한 코드를 살펴보겠다.
let mut test = ffi::Test::new().within_unique_ptr();
let_cxx_string!(name = "dog");
test.pin_mut().set_name(&name);
let test_name = test.pin_mut().get_name();
println!("test name : {}", test_name);
Test::new()를 통해서 객체를 만들어준다. c++코드에서 Test class에 생성자를 지정하지 않으면 기본적으로 new
함수를 생성해주는 것 같다. let_cxx_string!
매크로를 통해서 CxxString 타입의 문자열을 만들어준다. Test
객체의 메서드들을 통해서 내부 필드 값을 초기화 후 읽는 코드이다.
마지막으로 build.rs
에
fn main() -> miette::Result<()> {
let include_path = std::path::PathBuf::from("src");
// This assumes all your C++ bindings are in main.rs
let mut b = autocxx_build::Builder::new("src/main.rs", &[&include_path]).build()?;
b.flag_if_supported("-std=c++14")
.compile("autocxx-demo"); // arbitrary library name, pick anything
println!("cargo:rerun-if-changed=src/main.rs");
// Add instructions to link to any C++ libraries you need.
Ok(())
}
header파일이 있는 경로와 c++ 객체를 사용할 경로를 지정해준다.
c++과 rust는 기본적으로 ffi가 완벽히 호환되지 않는다.
autocxx
, cxx
등 ffi 크레이트를 활용하여 c++의 코드를 rust에서, rust의 코드를 c++에서 사용할 수 있다.
좀더 깊은 내용은 https://google.github.io/autocxx/index.html에서 공부해야겠다.