【发布时间】:2013-01-28 12:59:00
【问题描述】:
我正在尝试从某些 C# 调用 Win32 DLL。 DLL函数声明如下:
extern "C" __declspec(dllexport) UINT foo(TCHAR** list[], int& listSize, TCHAR* error);
在 C# 中,我这样声明外部函数:
[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
static extern uint foo(StringBuilder[] list, ref int listSize, StringBuilder error);
我的问题与 list 参数有关,它是 StringBuilder 类的数组。
我调用DLL函数的一些测试代码如下: (注意:我意识到缺少边界检查等。在这个阶段,我只是想让事情正常进行)。
// allocate a buffer for a possible error message being returned
StringBuilder error = new StringBuilder(1000);
// allocate buffers for the list of strings returned
StringBuilder[] list = new StringBuilder[10];
for (int i = 0; i < 10; i++)
{
list[i] = new StringBuilder(1000);
}
int listSize = list.Length;
uint result = foo(list, ref listSize, error);
将 StringBuilder 作为 error 参数的缓冲区传递,可以正常工作。我可以在 DLL 中设置它的内容如下:
_tcscpy(error, _T("Something went wrong");
当 C# 调用 foo 返回时,string error 变量具有我们在 DLL 中设置的文本。
但是,我不知道如何编组 StringBuilder[] 列表 参数。
在 C++ 中,我可以设置 list 数组的内容:
_tcscpy((*list)[0], _T("First item"));
// and so on...
而且,即使没有由于任何可能的编组问题而发生崩溃,但 C# 中的 list 在对 foo() 的调用返回时,确实不包含我们在 C++ 中设置的任何字符串。
我猜测问题出在 DllImport 上,以及我如何声明 list 参数应该被编组。
顺便说一下,示例 DLL 有一个匹配函数,然后调用该函数以释放上面显示的示例 foo 返回的“TCHAR** 列表”。
【问题讨论】:
-
TCHAR** list[]?你有一个字符串数组,还是一个字符串数组的数组? -
指向 TCHAR 指针的指针数组。令人困惑,我知道。
-
那么为什么将托管签名定义为
StringBuilder[]?我猜这相当于TCHAR **。但两者都不适用于您的情况:)。 -
好吧,也许我的定义也是错误的。这都与我的问题有关,我正在努力工作。
-
对于error参数,StringBuilder效果很好,就是一个TCHAR*。所以,我假设对于 TCHAR** list[],StringBuilder 是正确的。
标签: c# .net dll marshalling dllimport