C ++中字符串的L前缀

时间:2010-11-03 12:00:24

标签: c# .net c++ interop marshalling

我有一个静态库。该库定义了以下函数

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

5 个答案:

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