google / autocxx

Tool for safe ergonomic Rust/C++ interop driven from existing C++ headers
https://docs.rs/autocxx
Apache License 2.0
2.25k stars 144 forks source link

string interpreted as [u64 ; 4usize] #1379

Open madushan1000 opened 4 months ago

madushan1000 commented 4 months ago

Describe the bug I'm trying to generate some bindings to ghidra sleigh library. In loadimage.hh file, the relevant section looks like this.

class LoadImage {
protected:
  string filename;      ///< Name of the loadimage
public:
  LoadImage(const string &f);   ///< LoadImage constructor
...
  virtual string getArchType(void) const=0; ///< Get a string indicating the architecture type
...
};

autocxx interprets string as [u64 ; 4usize].

output of RUST_BACKTRACE=1 RUST_LOG=autocxx_engine=info cargo build

...
    Struct { name: ghidra::RangeProperties, details: StructDetails { item: # [doc = " \\brief A partially parsed description of a Range\n\n Class that allows \\<range> tags to be parsed, when the address space doesn't yet exist"] # [repr (C)] pub struct RangeProperties { # [doc = "< Name of the address space containing the range"] spaceName : [u64 ; 4usize] 
...
    SubclassTraitItem { name: ghidra::LoadImage_getArchType_trait_item, details: SuperclassMethod { name: getArchType, receiver: ghidra::LoadImage, params: [autocxx_gen_this : & root :: ghidra :: LoadImage], param_names: [self], ret_type: -> [u64 ; 4usize], receiver_mutability: Const, requires_unsafe: None, is_pure_virtual: true } }
...
  --- stderr
  Error:   × the include_cpp! macro couldn't be expanded into Rust bindings to C++:
    │ Encountered type not yet supported by autocxx: [u64 ; 4usize]

To Reproduce I tried to get a minimal example for the bug, but couldn't, so the long way,

Install sleigh library(on Ubuntu 23.10) following this guide.

build.rs

fn main() -> miette::Result<()> {
    let path = std::path::PathBuf::from("../sleigh/install/include/sleigh/"); // include path
    let mut b = autocxx_build::Builder::new("src/main.rs", &[&path])
        .extra_clang_args(&["-std=c++17"])
        .build()?;
    b.flag_if_supported("-std=c++17").compile("autocxx-demo"); // arbitrary library name, pick anything
    println!("cargo::rustc-link-search=../sleigh/install/lib");
    println!("cargo::rustc-link-lib=sla");
    println!("cargo::rustc-link-lib=decomp");
    println!("cargo::rustc-link-lib=slaSupport");
    println!("cargo:rerun-if-changed=src/main.rs");
    Ok(())
}

main.rs

use autocxx::{include_cpp, subclass::subclass};

include_cpp! {
    #include "ghidra/loadimage.hh"
    safety!(unsafe)
    subclass!("ghidra::LoadImage", RustLoadImage)
}

#[subclass]
pub struct RustLoadImage;

fn main() {
    println!("test")
}

Expected behavior I think string should be interpreted as CxxString?

Additional context I can get it to generate correct code if include a typedef for string

namespace ghidra {
typedef std::basic_string<char> string;
...
class LoadImage {
...
}
adetaylor commented 1 month ago

Thanks - I'm afraid I'm realistically not going to get a chance to look into your reproduction steps here. You might be able to use these instructions to automatically reduce the test case, though it doesn't always work great.

madushan1000 commented 1 month ago

Hi, thank you. I tried those instructions at the time and it failed to run. I think this is some sort of a preprocessor issue failing to include all the cpp standard library headers. I decided to use ghidra bindings someone else wrote so I don't have the setup to reproduce it anymore unfortunately.