STATUS_HEAP_CORRUPTION 将数据从 Rust 发送到 C# DLL 时发生错误
STATUS_HEAP_CORRUPTION error occurred when send data from Rust to C# DLL
当我将字符串数据从 Rust 发送到 C# DLL 时,我遇到了一个问题。 Rust exe 将显示以下错误。
error: process didn't exit successfully: target\release\test.exe (exit code: 0xc0000374, STATUS_HEAP_CORRUPTION)
我发送数据几次后,Rust exe 会崩溃(无确切模式)。
下面是 Rust 如何与 C# DLL 通信的代码。
extern crate libloading;
fn call_dynamic(arg_1_str: &str, arg_2_int: i32) -> Result<i32, Box<dyn std::error::Error>> {
let arg_1_c_str = CString::new(arg_str_1).unwrap();
// This is intended
let arg_3_c_str = CString::new("").unwrap();
let arg_1_c_char = arg_1_c_str.as_ptr();
let arg_3_c_char = arg_3_c_str.as_ptr();
let lib = libloading::Library::new("Test.dll").unwrap();
unsafe {
let func: libloading::Symbol<
unsafe fn(
arg_1: *const c_char,
arg_2: i32,
arg_3: *const c_char,
) -> i32,
> = lib
.get(b"GetStatus")
.unwrap();
Ok(func(arg_1_c_char, arg_2_int, arg_3_c_char))
}
}
用于与外部DLL通信的库是libloading。
什么可能导致发生此错误?有什么方法可以解决这个问题?非常感谢您的帮助。
注意:我无法访问 C# DLL 的源代码。因此,我不知道里面发生了什么。
这里有一些 Java 有效的代码。我正在尝试在 Rust 中做同样的事情:
public interface TestDLL extends Library {
int GetStatus (String arg1, int arg2, String arg3);
}
public int GetStatusFromDLL (String arg1, int arg2) {
TestDLL test_dll = (TestDLL)Native.loadLibrary ("Test", TestDLL.class);
return test_dll.GetStatus (arg1, arg2, null);
}
此问题已通过将第三个参数 arg_3_c_str
从空字符串更改为空指针 ptr::null()
得到解决。最终解决方案如下
fn call_dynamic(arg_1_str: &str, arg_2_int: i32) -> Result<i32, Box<dyn std::error::Error>> {
let arg_1_c_str = CString::new(arg_str_1).unwrap();
let arg_1_c_char = arg_1_c_str.as_ptr();
let lib = libloading::Library::new("Test.dll").unwrap();
unsafe {
let func: libloading::Symbol<
unsafe fn(
arg_1: *const c_char,
arg_2: i32,
arg_3: *const c_char,
) -> i32,
> = lib
.get(b"GetStatus")
.unwrap();
Ok(func(arg_1_c_char, arg_2_int, ptr::null()))
}
}
@Jmb 指出了 Rust 和 Java 实现之间的区别,所有功劳归功于他。
但是,还有一个有趣的点可以讨论为什么传入空字符串而不是空指针会导致 STATUS_HEAP_CORRUPTION 错误。
当我将字符串数据从 Rust 发送到 C# DLL 时,我遇到了一个问题。 Rust exe 将显示以下错误。
error: process didn't exit successfully: target\release\test.exe (exit code: 0xc0000374, STATUS_HEAP_CORRUPTION)
我发送数据几次后,Rust exe 会崩溃(无确切模式)。
下面是 Rust 如何与 C# DLL 通信的代码。
extern crate libloading;
fn call_dynamic(arg_1_str: &str, arg_2_int: i32) -> Result<i32, Box<dyn std::error::Error>> {
let arg_1_c_str = CString::new(arg_str_1).unwrap();
// This is intended
let arg_3_c_str = CString::new("").unwrap();
let arg_1_c_char = arg_1_c_str.as_ptr();
let arg_3_c_char = arg_3_c_str.as_ptr();
let lib = libloading::Library::new("Test.dll").unwrap();
unsafe {
let func: libloading::Symbol<
unsafe fn(
arg_1: *const c_char,
arg_2: i32,
arg_3: *const c_char,
) -> i32,
> = lib
.get(b"GetStatus")
.unwrap();
Ok(func(arg_1_c_char, arg_2_int, arg_3_c_char))
}
}
用于与外部DLL通信的库是libloading。
什么可能导致发生此错误?有什么方法可以解决这个问题?非常感谢您的帮助。
注意:我无法访问 C# DLL 的源代码。因此,我不知道里面发生了什么。
这里有一些 Java 有效的代码。我正在尝试在 Rust 中做同样的事情:
public interface TestDLL extends Library {
int GetStatus (String arg1, int arg2, String arg3);
}
public int GetStatusFromDLL (String arg1, int arg2) {
TestDLL test_dll = (TestDLL)Native.loadLibrary ("Test", TestDLL.class);
return test_dll.GetStatus (arg1, arg2, null);
}
此问题已通过将第三个参数 arg_3_c_str
从空字符串更改为空指针 ptr::null()
得到解决。最终解决方案如下
fn call_dynamic(arg_1_str: &str, arg_2_int: i32) -> Result<i32, Box<dyn std::error::Error>> {
let arg_1_c_str = CString::new(arg_str_1).unwrap();
let arg_1_c_char = arg_1_c_str.as_ptr();
let lib = libloading::Library::new("Test.dll").unwrap();
unsafe {
let func: libloading::Symbol<
unsafe fn(
arg_1: *const c_char,
arg_2: i32,
arg_3: *const c_char,
) -> i32,
> = lib
.get(b"GetStatus")
.unwrap();
Ok(func(arg_1_c_char, arg_2_int, ptr::null()))
}
}
@Jmb 指出了 Rust 和 Java 实现之间的区别,所有功劳归功于他。
但是,还有一个有趣的点可以讨论为什么传入空字符串而不是空指针会导致 STATUS_HEAP_CORRUPTION 错误。