【发布时间】:2016-10-17 15:17:26
【问题描述】:
我有一个用 C 语言编写的大型库,我想在 C# 程序中用作 DLL。大多数 C 代码将由库自己的函数使用,但我确实需要一个函数才能从 C# 项目中调用。
所以下面有一个示例 C 函数
__declspec(dllexport) char* test(char* a){
char* b = "World";
char* result = malloc(strlen(a) + strlen(b) + 1);
strcpy(result, a);
strcpy(result, b);
return result;
}
现在在 C# 代码中我得到了using System.Running.InteropServices;
还有[DllImport("mydll.dll")],但我不确定如何声明该函数。
public static extern char* test(char* a); 显然不起作用,因为 C# 不像 C 那样支持指针。
那么我应该如何将一个字符串传递给这个 C 函数并让它也返回一个字符串呢?
【问题讨论】:
-
你必须使用 C 库吗?为什么你不能编写自己的方法来在 C# 中处理同样的事情?在我看来这似乎很简单..
-
C# 确实支持指针,就像 C 一样,但您在这里不需要它们。您的函数返回
int但您试图返回char*- 这是一个错误。通常你为函数提供一个缓冲区来填充,或者你必须导出第二个函数来释放你分配的字符串。 -
返回这样的字符串是一种泄漏。请参阅stackoverflow.com/questions/5298268/… 了解正确的做法。
-
@MethodMan 这只是一个例子。真正的 C 代码要深入得多。
-
参数只是字符串。然而,返回值是一个问题,pinvoke marshaller 将尝试使用 CoTaskMemFree() 释放字符串缓冲区,但这是行不通的。请注意,这个函数也很难从 C 程序中可靠地调用。您需要公开另一个调用 free() 的辅助函数。在 C# 中声明为 IntPtr 并使用 Marshal.PtrToStringAnsi()。更智能的签名是 int test(const char* a, char* buffer, int buflen),允许您将第二个参数声明为 StringBuilder,并在 buflen 不够大时返回错误代码。