我有一个静态库。该库定义了以下函数
int WriteData(LPTSTR s)
调用该函数的示例是
LPTSTR s = (LPTSTR) L"Test Data";
int n = WriteData(s);
WriteData在成功时返回0,在失败时返回-1。
我正在编写动态DLL来导出此函数。
int TestFun(LPTSTR lpData)
{
return WriteData(lpData);
}
C ++测试应用程序结果
LPTSTR s = (LPTSTR) L"Test Data";
TestFun(s); //OK return 0
LPTSTR s = (LPTSTR) "Test Data";
TestFun(s); //Fail return -1
我必须从c#应用程序中调用它。我假设我的DLL-Import签名是:
[DllImport("Test.dll")]
private static extern int TestFun(String s);
我的问题非常简单如何从.Net调用它? 如你所见,我可以控制
TestFun(LPTSTR lpData)
但无法控制
WriteData(LPTSTR s)
感谢大家的投入。到目前为止,我仍然坚持施法。我认为当我能够从用户那里获取输入并写下2行代替以下行时,我的问题就会得到解决。
LPTSTR s = (LPTSTR) L"Test Data"); //<= How can ii take input from user and
TestFun(s); //OK return 0
答案 0 :(得分:7)
L前缀使字符串成为wchar_t字符串。
您可以使用Windows API函数MultiByteToWideChar
将ANSI字符串转换为wchar_t字符串。
答案 1 :(得分:6)
执行L前缀的特定“功能”是宏TEXT()
或_T()
。 (TEXT由Windows SDK定义,_T是Microsoft C Runtime的扩展名。)
当您的项目构建时使用unicode支持(这是大多数MS Dev环境中现在的新项目的默认设置)时,这些函数会自动添加L前缀 - 或者为非unicode(或ansi)配置的项目保留它。 / p>
不要这样做:
LPTSTR s = (LPTSTR) L"ABC"; // Working fine
WriteData(s);
如果项目曾经配置为非Unicode,那么L“ABC”仍然是一个宽字符数组,但LPTSTR将成为指向8位字符数组的指针。
这是如何正确地将字符串分配给Ansi,Unicode或“Text”字符串。 (文本可以是Ansi或Unicode,具体取决于项目设置)(由于其冗余,我保留了L,并添加了C,因为字符串文字应该是常量)。
PCSTR p1 = "ABC";
PCWSTR p2 = L"ABC";
PCTSTR p3 = TEXT("ABC");
答案 2 :(得分:1)
我觉得你很困惑,因为你的功能应该可以正常工作:
int TestFun(LPTSTR lpData)
{
return WriteData(lpData); // Should be happy
}
但是当你调用你的功能时,你必须要小心:
TestFun((LPTSTR) L"ABC"); // Will work fine
TestFun((LPTSTR) "ABC"); // Will not work
这是因为“ABC”和L“ABC”是两回事。如果你在记忆中看它们:
"ABC" | 65 66 67 00
L"ABC" | 65 00 66 00 67 00 00 00
已编辑添加:
.Net中没有像L前缀
这是错误的。我刚刚在VisualStudio中打开了“New Project-&gt; C ++ - &gt; CLR Console”,第一行是:
Console::WriteLine(L"Hello World");
答案 3 :(得分:1)
尝试:
[DllImport("Test.dll")]
private static extern int TestFun([MarshalAs(UnmanagedType.LPTStr)] string s);
有关使用MSDN上的MarshalAsAttribute封送的更多信息。
答案 4 :(得分:0)
我会将你的字符串包装在_T(...)
宏中。这样,它可以在ANSI和UNICODE构建之间移植。
请注意,您使用的是可移植字符串类型 - LPTSTR
- 请注意T
。它将根据构建设置在ANSI和UNICODE之间进行更改。