Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for well-known C++ types #738

Open
jcranmer opened this issue Jun 8, 2017 · 7 comments
Open

Better support for well-known C++ types #738

jcranmer opened this issue Jun 8, 2017 · 7 comments

Comments

@jcranmer
Copy link

jcranmer commented Jun 8, 2017

Certain types like std::string or std::vector are quite common in C++ code, yet trying to run them through bindgen tends to be a nightmare because their implementations are actually very complicated. There are also types like string_view or llvm::StringRef that are conceptually identical to native Rust types (&str, in this case, sidestepping the issue of UTF-8/non-UTF-8) that would be useful to have represented as the native Rust type in function calls.

Rather than trying to work towards getting all the functionality necessary to build std::string (which is really a complex template that no one uses as such), it makes sense to provide a dedicated mapping mechanism specifically for the std::string type. This could perhaps be done by giving a mechanism to say "where you see type T as a function parameter in C/C++, use RustTy instead for the Rust code" and providing code to map between the C++ and Rust types.

@dmilith
Copy link

dmilith commented Dec 13, 2018

I lost last few days trying to read a freaking C++ function returning std::string… to use it from Rust side… STL is a hellhole of complexity… and I've failed :(
When I use const char* instead.. it's leaking memory like a dog…

@jeffvandyke
Copy link

We have a case where, when interacting with Windows, std::wstring was useful, so it might be good to keep in mind other string types besides std::string, but an easy-to-use mapping from C++'s std::string to Rust's std::string::String would handle many cases.

This, of course, is part of a bigger problem of easier mapping to STL types (like std::vector, std::map, and perhaps other non-collection types), to which a consistent solution for the individual types would probably make interop with C++ easier for everyone

@jonhoo
Copy link
Contributor

jonhoo commented Nov 13, 2019

I'm curious -- what is currently the way to work around issues that arise around these types? For example, I'm currently struggling with a header file that ends up with a #include "string_view.hpp" (this file specifically), and it causes bindgen to choke with

[2019-11-13T00:08:29Z DEBUG bindgen::ir::context] BindgenContext::add_item(Item { id: ItemId(95897), local_id: Cell { value: None }, next_child_local_id: Cell { value: 1 }, canonical_name_cache: RefCell { value: None }, comment: None, annotations: Annotations { opaque: false, hide: false, use_instead_of: None, disallow_copy: false, private_fields: None, accessor_kind: None, constify_enum_variant: false, derives: [] }, parent_id: ItemId(95824), kind: Type(Type { name: Some("u32string_view"), layout: Some(Layout { size: 16, align: 8, packed: false }), kind: Alias(TypeId(ItemId(95898))), is_const: false }) }, declaration: Some(Cursor(u32string_view kind: TypedefDecl, loc: external/plasma/cpp/src/arrow/vendored/string_view.hpp:1143:38, usr: Some("c:string_view.hpp@N@nonstd@N@sv_lite@T@u32string_view"))), loc: Some(Cursor(u32string_view kind: TypedefDecl, loc: external/plasma/cpp/src/arrow/vendored/string_view.hpp:1143:38, usr: Some("c:string_view.hpp@N@nonstd@N@sv_lite@T@u32string_view")))
[2019-11-13T00:08:29Z DEBUG bindgen::ir::context] add_item_to_module: adding ItemId(95897) as child of parent module ItemId(95824)
thread 'main' panicked at 'Unknown token while processing namespace: ClangToken { spelling: CXString { data: 0x55d7af5201f0, private_flags: 1 }, kind: 0 }', /home/jon/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/bindgen-0.51.1/src/ir/context.rs:2164:21

How do I work around this? Marking the type as opaque won't actually prevent bindgen from trying to parse the include file it seems.

@Volker-Weissmann
Copy link
Contributor

What is the currently recommended way to call a c++ function that wants a std::string argument from rust?

@auscompgeek
Copy link
Contributor

What is the currently recommended way to call a c++ function that wants a std::string argument from rust?

Two options I'm aware of:

  • Write a C wrapper around the function that takes a C string.
  • Use the cxx crate.

@adetaylor
Copy link
Contributor

I am about to embark on an endeavor to adjust a fork of bindgen to output a #[cxx::bridge] section as required by the cxx crate, instead of plain Rust. The idea is to provide just the sort of thing described here — passing standard C++ types safely between C++ and Rust, generating suitable binding code on both sides, based on declarations and definitions in existing C++ headers.

If this works out (even a little bit) I'll discuss how/whether these changes can be submitted to bindgen or if they should forever live in a fork, or if bindgen can be made modular in some way to support this. There's a bit of discussion on this plan here.

This will be not be a high priority project for me, so expect not to hear anything for months. But if anyone wants to collaborate, please get in touch!

@barakugav
Copy link

I would really appreciate a support for std::vector<T>.
Maybe im missing something but I can't get it to work, does anyone have a working solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

11 participants