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之间进行更改。