从C打印时,为什么更改了CString指针值?

时间:2018-12-08 05:09:51

标签: c rust ffi

我正在从C调用Rust函数,但是返回时指针地址会更改。

ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    saveBitmap.compress(Bitmap.CompressFormat.JPEG, 75, baos);
                    String path = MediaStore.Images.Media.insertImage(getContentResolver(),saveBitmap,"Title",null);
#[no_mangle]
pub extern fn plugin_get_config_string(config: *const toml::Value, k: *const c_char) -> *const c_char {
    let a = CString::new("dwadwad").unwrap();
    let p = a.as_ptr();
    println!("{:?}", p);
    mem::forget(a);
    p
}   

在Rust中:__declspec(dllexport) void initialize(void *config) { char *dwad = plugin_get_config_string(config, "host"); printf("%p\n", dwad); }

在C中:0x220d3ceee30

前3个字节始终用C剥离。

我正在使用Visual Studio 2017 x64开发命令提示符和stable-x86_64-pc-windows-msvc。

有人知道可能是什么问题吗?

1 个答案:

答案 0 :(得分:3)

在您的C代码中,plugin_get_config_string没有原型。因此,编译器推断返回类型为int。然后将该int分配给char *变量时,int被符号扩展,因为在目标平台上char *大于int

该函数的参数采用相同的推理:它们隐式定义为int,因此来自C的指针将被截断,并且由于大小不匹配,参数可能位于错误的位置。

要解决此问题,必须声明一个这样的原型:

const char *plugin_get_config_string(const void *config, const char *k);