如何通过引用修改该字符串的非托管 C 库来发送字符串?
我是与非托管库交互的新手。我有一个非托管 C 函数,它通过函数内的引用修改字符串。我在从 C# 传递字符串并通过 C 函数修改它时遇到问题。
这是 C 函数:
__declspec(dllexport) void __stdcall Test(char* name)
{
*name = "Bar";
}
这是 C# DLL 导入代码:
[DllImport(@"C:/blah/mylibrary.dll")]
public extern static string Test(string name);
这是我用来调用该函数的代码:
string s = "foo";
Test(s);
//I want s to be "Bar" after the above line
我尝试在字符串参数上使用“ref”和“out”,并尝试将其编组为 LPStr。根据我的尝试,我要么收到类似的错误
“作为字符串传入的指针不得位于进程地址空间的底部 64K。”
或者
“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”
我确信我只是用我的指点做了一些愚蠢的事情。有人可以帮助我确定适当的 C# 代码以使“s”等于“bar”吗?
谢谢
I am new to the world of interacting with unmanaged libraries. I have an unmanaged C function that modifies a string by reference within the function. I'm having trouble passing a string from C# and getting it modified by the C function.
Here's the C function:
__declspec(dllexport) void __stdcall Test(char* name)
{
*name = "Bar";
}
This is the C# DLL import code:
[DllImport(@"C:/blah/mylibrary.dll")]
public extern static string Test(string name);
This is the code I'm using to call the function:
string s = "foo";
Test(s);
//I want s to be "Bar" after the above line
I have tried using "ref" and "out" on the string parameter, and tried Marshalling as an LPStr. Depending on what I try, I either get an error like
"The pointer passed in as a String must not be in the bottom 64K of the process's address space."
or
"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
I'm sure I'm just doing something stupid with my pointers. Can someone help me determine the appropriate C# code to get "s" to equal "bar"?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的 C
Test
函数没有执行您所说的任何操作。它所做的只是获取一个局部变量(name
)并将其分配给一个固定字符串。要执行您所说的操作,必须对name
指向的地址执行复制操作:当然,这样的操作在等待中是一场灾难,因为您函数签名不正确(未指定缓冲区长度)。
考虑到 C 函数如上所示,那么您应该遵循 Default Marshaling 中指定的规则对于字符串:
因此,您的 DLL 应该如下所示:
并通过传递适当大小的 StringBuilder 来调用它:
如果添加长度参数,C 接口将添加一些理智。
Your C
Test
function doesn't do anything like you said it does. All it does it takes a local variable (name
) and assigns it to a fixed string. To do what you said it does it would had to do a copy operation into the address pointed to byname
:Of course, such an operation is a disaster in waiting since you have incorrect function signature (buffer lengths are not specified).
Considering that the C function is as above, then you should follow the rules specified at Default Marshaling for Strings:
So your DLL should be like this:
and call it by passing a properly sized
StringBuilder
:Some sanity would be added to the C interface if you add a length parameter.