C ++中字符串的L前缀
我有一个静态库。 该库定义了以下function
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
我必须从ac#应用程序调用它。 我假设我的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
L前缀使字符串成为wchar_t字符串。 您可以使用Windows API函数MultiByteToWideChar
将ANSI字符串转换为wchar_t字符串。
执行L前缀的特定“函数”是宏TEXT()
或_T()
。 (TEXT由Windows SDK定义,_T是Microsoft C Runtime的扩展)。
当您的项目构建时支持unicode(这是大多数MS Dev环境中现在的新项目的默认设置)时,这些函数会自动添加L前缀 – 或者为非unicode(或ansi)配置的项目保留它。
不要做这个演员:
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");
我觉得你很困惑,因为你的function应该可以正常工作:
int TestFun(LPTSTR lpData) { return WriteData(lpData); // Should be happy }
但是当你打电话给你的function时,你必须要小心:
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-> C ++ – > CLR Console”,第一行是:
Console::WriteLine(L"Hello World");
尝试:
[DllImport("Test.dll")] private static extern int TestFun([MarshalAs(UnmanagedType.LPTStr)] string s);
有关使用MSDN上的MarshalAsAttribute封送的更多信息。
我会把你的字符串包装在_T(...)
宏中。 这样它可以在ANSI和UNICODE构建之间移植。
请注意,您使用的是便携式字符串类型 – LPTSTR
– 请注意T
它将根据构建设置在ANSI和UNICODE之间进行更改。