代码之家  ›  专栏  ›  技术社区  ›  Manjoor

C++中字符串的L前缀

  •  7
  • Manjoor  · 技术社区  · 14 年前

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

    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导入签名是:

            [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 回复  |  直到 14 年前
        1
  •  7
  •   harper    14 年前

    l前缀使字符串成为wchar_t字符串。 您可以使用Windows API函数 MultiByteToWideChar 将ansi字符串转换为wchar_t字符串。

        2
  •  6
  •   Chris Becke    14 年前

    执行l前缀的特定“函数”是一个宏 TEXT() _T() . (文本由Windows SDK定义,_t是Microsoft C运行时的扩展)。

    当您的项目构建时启用了Unicode支持(在大多数MS dev环境中,这是新项目的默认支持),这些函数会自动添加l前缀,或者对于非Unicode(或ANSI)配置的项目不使用。

    不要这样做:

    LPTSTR s = (LPTSTR) L"ABC";   // Working fine
         WriteData(s);
    

    如果项目曾经配置为非Unicode,那么l“abc”仍然是一个宽字符数组,但是lptstr将成为指向8位字符数组的指针。

    这是如何将字符串正确分配给ANSI、Unicode或“文本”字符串的方法。(根据项目设置,文本可以是ansi或unicode)(因为L是多余的,所以我省略了L,并添加了C,因为字符串文本应该是常量)。

    PCSTR p1 = "ABC";
    PCWSTR p2 = L"ABC";
    PCTSTR p3 = TEXT("ABC");
    
        3
  •  1
  •   egrunin    14 年前

    我觉得你很困惑,因为你的功能应该可以正常工作:

    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"  | 65 66 67 00
    L"ABC" | 65 00 66 00 67 00 00 00
    

    编辑添加:

    在.NET中没有类似l前缀的内容

    这是错误的 . 我刚刚在VisualStudio开设了“新项目-gt;c++& gt;CLR控制台”,第一行是:

    Console::WriteLine(L"Hello World");
    
        4
  •  1
  •   Joshua Rodgers    14 年前

    尝试:

    [DllImport("Test.dll")]
    private static extern int TestFun([MarshalAs(UnmanagedType.LPTStr)] string s);
    

    有关使用上的MarshalAsAttribute封送的详细信息 MSDN

        5
  •  0
  •   Daniel A. White    14 年前

    我会用 _T(...) 宏。这样就可以在ansi和unicode构建之间进行移植。

    请注意,您使用的是可移植字符串类型- LPTSTR -注意 T . 它将根据生成设置在ANSI和Unicode之间进行更改。