【问题标题】:C from C#: string as parameter and return value?C 来自 C#:字符串作为参数和返回值?
【发布时间】:2015-09-14 19:49:56
【问题描述】:

我在 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);
}

这很好用,但我希望函数返回 char *... 并返回 message 变量。

当我将doThis 更改为返回char *,并且调用代码期望string 时,Win32 主机在运行时崩溃。

有什么建议吗?

[奇怪的是,我想我之前有这个工作]

【问题讨论】:

标签: c# .net c interop


【解决方案1】:

让我们假设这个签名暂时有效:

__declspec(dllexport) char* doThis(char* message)

你从 C# 调用它,然后你有一个char*。你把它复制到string,然后......然后什么?你用那个char*做什么?

你会打电话给free吗?顺便说一下哪个 C 运行时库的free?或者也许你不应该因为指针可能来自静态内存?你不知道,.NET mashaller 也不知道。


处理此问题的正确方法是传递第二个char* 参数,该参数指向分配的一些缓冲区youyou 负责释放。 p>

嗯,在 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();

编组员为您处理管道。

【讨论】:

  • 惊人的答案有很多惊人的点,包括如果它是 C++ 的区别,以及考虑一旦返回对象你将如何处理。谢谢。
  • 还有一个问题:如果它是一个 StringBuilder 对象数组,我可以通过...ArrayList吗?
  • 我不这么认为。您可以直接传递char**(或IntPtr)并自己管理内存,或者您可以使用C++/CLI 作为互操作层。 P/Invoke 仅适用于最常见的情况,对于更复杂的情况,您必须自己完成。
猜你喜欢
  • 2023-03-10
  • 1970-01-01
  • 2018-03-14
  • 2012-07-30
  • 2021-12-27
  • 2015-12-28
  • 2014-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多