rust-lang / rust-lang/rust-bindgen

Conversion between Rust String and opaque std_string

Open
#2,072 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

I want to call c++ code in my Rust code, so I am using bindgen to generate the FFI code. However, I do not know how to convert the String to string in c++ in my Rust code.

C++ demo code:

#include <string>

class Foo
{
private:
	std::string m_value;

public:
	Foo();
	std::string get_string_value();
	std::string set_string_value(std::string s);
};

Foo::Foo()
{
	m_value = "test";
};

std::string Foo::get_string_value()
{
	return m_value;
}

std::string Foo::set_string_value(std::string s)
{
	m_value = s;
}

build.rs:

	let bindings = bindgen::Builder::default()
		.header("wrapper.hpp")
		.clang_args(&["-x", "c++", "-std=c++11"])
		.allowlist_type("Foo")
		.opaque_type("std::.*")
		.parse_callbacks(Box::new(bindgen::CargoCallbacks))
		.generate()
		.expect("Unable to generate bindings");

The std_string defined in FFI code is like this:

pub type std_string = [u64; 4usize];
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
    pub m_value: std_string,
}
extern "C" {
    #[link_name = "\u{1}_ZN3Foo16get_string_valueB5cxx11Ev"]
    pub fn Foo_get_string_value(this: *mut Foo) -> std_string;
}
extern "C" {
    #[link_name = "\u{1}_ZN3Foo16set_string_valueENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"]
    pub fn Foo_set_string_value(this: *mut Foo, s: std_string) -> std_string;
}
extern "C" {
    #[link_name = "\u{1}_ZN3FooC1Ev"]
    pub fn Foo_Foo(this: *mut Foo);
}
impl Foo {
    #[inline]
    pub unsafe fn get_string_value(&mut self) -> std_string {
        Foo_get_string_value(self)
    }
    #[inline]
    pub unsafe fn set_string_value(&mut self, s: std_string) -> std_string {
        Foo_set_string_value(self, s)
    }
    #[inline]
    pub unsafe fn new() -> Self {
        let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit();
        Foo_Foo(__bindgen_tmp.as_mut_ptr());
        __bindgen_tmp.assume_init()
    }
}

How can I use set_string_value() function in my Rust code? It accepts std_string, but I can not convert the String type to std_string type.

Thanks in advance!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with build.rs, wrapper.hpp, and the generated std_string and Foo bindings shown in the report. Check bindgen's documented handling of opaque C++ std::string and the ABI of the generated set_string_value signature. Done means establishing a supported way to pass and receive the C++ string, or clearly documenting the required wrapper approach.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, rust
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.