我正在开发 C# 应用程序(在我的应用程序中使用 win 32 dll)...我正在尝试这样的事情 在 DLL(test.dll) 中:
char* Connect(TCHAR* lpPostData)
{
char buffer[1000];
.....
return buffer;
}
在 C# 应用程序中:
[DllImport("test.dll", EntryPoint = "Connect", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string Connect(StringBuilder postdata);
string returnedData = Connect(postdata);
但是数据返回并没有正常发生.... 请任何人告诉我哪里错了 提前致谢
最佳答案
TCHAR * in 告诉我它是一个 unicode 输入(UNICODE 是在 CE 下定义的),但是 char * 告诉我它可能是一个字节数组(或 ascii 字符串)并且应该责备创建此 API 的人将两者混合,因为这真是非常糟糕的设计。
您当然不能将返回值编码为宽字符串,因为它不是一个。在桌面上,您会使用 Tony 的建议,但 MSDN(和实践)clearly shows它在 CF 中不可用(不知道为什么 MS 认为我们不需要它)。
智能设备框架 does have it .另一种选择是使用 Marshal 从返回的指针复制到字节数组,然后使用 Encoding.ASCII 将该数组转换为字符串。当然,这指出了此 API 中的另一个明显缺陷,即它 shouldn't be returning a string首先。
编辑 1
由于我看到其他关于您应该做什么的建议我并不完全同意,我想我应该给您举个例子:
您的 native 调用应该更像这样:
extern "C"
__declspec(dllexport)
const BOOL __cdecl Connect(TCHAR* lpPostData,
TCHAR *returnBuffer,
DWORD *returnSize)
{
// validate returnSize, returnBuffer, etc
// write your data into returnBuffer
TCHAR *data = _T("this is my data");
_tcscpy(returnBuffer, data);
*returnSize = (_tcslen(data) + 1) * sizeof(TCHAR);
return succeeded;
}
请注意,我只是返回一个成功代码。文本数据作为指针连同它的长度一起传入(因此 API 知道它可以使用多少空间并可以返回它使用了多少空间)。也不是说我与我的字符串变量数据类型一致,我使用的是 TCHAR 宏,它将在 CE 下变为 wchar_t,这与操作系统的其余部分(几乎没有 ASCII API 开始)一致。
大多数 WIn32 API 集的工作方式完全相同。
您的 P/Invoke 声明非常简单:
[DllImport("test.dll", SetLastError=true)]
private static extern bool Connect(string postData,
StringBuilder data,
ref int length);
使用起来也很简单:
void Foo()
{
int length = 260;
StringBuilder sb = new StringBuilder(length);
if(Connect("Bar", sb, ref length))
{
// do something useful
}
}
请注意,StringBuilder 必须初始化为某个大小,该大小是您在第三个参数之前传递的大小。
关于c# - 在 C# 应用程序中使用 Win32 dll(将 char* 返回到 C# 问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2176254/