您的C++函数实现与C#函数声明的预期不匹配.
C#字节数组作为指向数组原始内存的固定指针编组到函数中.您在C++代码中为参数(std::byte buf[256]
)使用的语法只是语法糖,编译器实际上将其视为指针(std::byte* buf
).在这种情况下这很好.但是,您的C++函数实际上并没有将指针指向的任何内容复制到内存中.您只需将指针本身更改为指向不同的内存地址.指针本身是一个局部变量,因此当函数退出时,指针将不再存在,并且不管它指向什么.
此外,C#声明期望函数返回可以封送到的内容.NET string
,但C++函数实际上并没有return
'ing任何东西.string
返回值的默认编组行为为UnmanagedType.LPStr
,因此C++函数需要返回指向以null结尾的char*
字符串的指针.该字符串的内存必须分配CoTaskMemAlloc()
,因为封送拆收器将获得内存的所有权,并在将char
个数据转换为string
后释放CoTaskMemFree()
个内存.
此外,C++函数没有定义调用约定,因此它将使用编译器的默认值(通常为__cdecl
,除非您更改编译器的设置).但是,默认的调用约定是.NET的DllImport
期望使用的C++函数是__stdcall
(为了与Win32 API兼容).这种不匹配在64位中无关紧要,但在32位中却很重要.
在不更改C#声明的情况下,在C++端try 以下操作:
char* __stdcall Name(std::byte buf[256])
{
std::string s{ "test" };
size_t size = s.size() + 1;
memcpy(buf, s.c_str(), size);
void *ptr = CoTaskMemAlloc(size);
memcpy(ptr, s.c_str(), size);
return ptr;
}
这就是说,让一个函数同时在字节数组输出参数和返回值中返回字符串是很奇怪的.您确定字节数组不是要用作输入参数,而是函数解析其内容以提取amd字符串吗?这会更有意义.如果你能更新你的问题来展示你的答案,这将非常有帮助.NET代码实际上是调用C++函数并使用字节array.