我在Win32 DLL的<div id="navPlaceHolder"></div>
//css
#navPlaceHolder{
height:50px;
visibility:hidden;
}
文件中调用doThis
函数。
.c
使用此调用代码:
#include <stdio.h>
__declspec(dllexport) double doThis( char *message)
{
printf("do nothing much");
return 32.5;
}
工作正常,但我希望函数返回[DllImport(@"\\vmware-host\Shared Folders\c-sharp\Hot\MusicIO\Debug\HelloWorld.dll",
CallingConvention=CallingConvention.Cdecl)]
public static extern double doThis(string message);
private void button1_Click(object sender, EventArgs e)
{
double returned = doThis("what 2");
MessageBox.Show("Click " + returned);
}
...并返回char *
变量。
当我更改message
以返回doThis
,并且调用代码期望char *
时,Win32主机在运行时崩溃。
有什么建议吗?
[奇怪的是,我认为我之前就已经开始工作了]
答案 0 :(得分:2)
让我们假设这个签名有一段时间了:
__declspec(dllexport) char* doThis(char* message)
你从C#调用它然后你有一个char*
。你将它复制到string
,然后......然后什么?你对char*
做了什么?
你打电话给free
吗?那个哪个 C运行时库的free
?或者你可能不应该因为指针可能来自静态内存?你不知道,.NET mashaller也不知道。
处理此问题的正确方法是传递第二个char*
参数,该参数指向您分配的某个缓冲区,您负责释放。
好吧,在C#中,实际上并不是你。编组员可以为你处理这个问题。
所以定义这样的签名:
__declspec(dllexport) double doThis(char* message, char* output, int maxOutputLength)
maxOutputLength
参数是一种安全措施,让您的C代码知道消息的最大长度。根据您的C代码使用它。
注意:在C ++代码中,message
为const char*
,而output
仍为char*
。
在C#方面,签名将涉及StringBuilder
:
[DllImport(@"HelloWorld.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern double doThis(string message, StringBuilder output, int maxOutputLength);
然后,您分配一个具有初始容量的StringBuilder
,并将其传递给:
var output = new StringBuilder(1024);
double returned = doThis("what 2", output, output.Capacity);
var outputStr = output.ToString();
marshaller为你处理管道。