来自 C# 的 C:字符串作为参数和 return 值?
C from C#: string as parameter and return value?
我在 Win32 DLL 的 .c
文件中调用 doThis
函数。
#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);
}
工作正常,但我希望函数 return char *
... 和 return message
变量。
当我将 doThis
更改为 return 和 char *
并且调用代码期望 string
时,Win32 主机在运行时崩溃。
有什么建议吗?
[奇怪的是,我想我之前有这个工作]
让我们假设这个签名工作了一段时间:
__declspec(dllexport) char* doThis(char* message)
你从 C# 调用它,然后你有一个 char*
。你把它复制到 string
,然后……然后 什么? 你用那个 char*
做什么?
你打电话给 free
吗? 哪个的free
C运行时库?或者你不应该因为指针可能来自静态内存?你不知道,.NET mashaller 也不知道。
处理这个问题的正确方法是传递第二个 char*
参数,它指向某个缓冲区 you 已分配,并且 you负责释放。
好吧,在 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();
编组人员会为您处理管道。
我在 Win32 DLL 的 .c
文件中调用 doThis
函数。
#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);
}
工作正常,但我希望函数 return char *
... 和 return message
变量。
当我将 doThis
更改为 return 和 char *
并且调用代码期望 string
时,Win32 主机在运行时崩溃。
有什么建议吗?
[奇怪的是,我想我之前有这个工作]
让我们假设这个签名工作了一段时间:
__declspec(dllexport) char* doThis(char* message)
你从 C# 调用它,然后你有一个 char*
。你把它复制到 string
,然后……然后 什么? 你用那个 char*
做什么?
你打电话给 free
吗? 哪个的free
C运行时库?或者你不应该因为指针可能来自静态内存?你不知道,.NET mashaller 也不知道。
处理这个问题的正确方法是传递第二个 char*
参数,它指向某个缓冲区 you 已分配,并且 you负责释放。
好吧,在 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();
编组人员会为您处理管道。