C++ 中字符串的 L 前缀

发布于 2024-09-30 22:28:38 字数 1045 浏览 1 评论 0原文

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

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

        [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

I have a static library. This library have the following function defined

int WriteData(LPTSTR s)

The sample to call the function is

LPTSTR s = (LPTSTR) L"Test Data";   
int n = WriteData(s);

WriteData return 0 on success and -1 on failure.

I am writing a dynamic DLL to export this function.

int TestFun(LPTSTR lpData)
{
   return  WriteData(lpData);
}

A C++ test application result

LPTSTR s = (LPTSTR) L"Test Data";   
TestFun(s);  //OK  return 0

LPTSTR s = (LPTSTR) "Test Data";    
TestFun(s);  //Fail  return -1

I have to call it from a c# application. I assume my DLL-Import signature would be:

        [DllImport("Test.dll")]
        private static extern int TestFun(String s);

My question is very simple How can i call it from .Net?
As you can see i have control over

TestFun(LPTSTR lpData)

but no control over

WriteData(LPTSTR s)

Thanks everybody for their input. So far i am stuck on casting. I think my problem would be solved when i woul be able take input from user and write 2 line for casting in place of following line.

   LPTSTR s = (LPTSTR) L"Test Data"); //<= How can ii take input from user and 
    TestFun(s);  //OK  return 0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一场信仰旅途 2024-10-07 22:28:38

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

The L prefix makes the string a wchar_t string.
You can use the Windows API function MultiByteToWideChar to convert an ANSI string to a wchar_t string.

枕梦 2024-10-07 22:28:38

执行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 或“文本”字符串的方法。 (文本可以是 Ansi 或 Unicode,具体取决于项目设置)(我省略了 L,因为它是多余的,并添加了 C,因为字符串文字应该是常量)。

PCSTR p1 = "ABC";
PCWSTR p2 = L"ABC";
PCTSTR p3 = TEXT("ABC");

The specific "function" to perform the L prefix is a macro TEXT() or _T(). (TEXT is defined by the Windows SDK, _T is an extension of the Microsoft C Runtime).

These functions automatically add the L prefix when your project is built with unicode support on (which is the default for new projects now in most MS Dev environments) - or leave it off for non unicode (or ansi) configured projects.

Don't do this cast:

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

If the project was ever configured for non Unicode, then L"ABC" would still be an array of wide-characters, but LPTSTR would become a pointer to an array of 8bit characters.

This is how to correctly assign a string to an Ansi, Unicode, or "Text" string. (Text can be Ansi or Unicode depending on project settings) (I left off the L because its redundant, and added a C, because string literals should be constant).

PCSTR p1 = "ABC";
PCWSTR p2 = L"ABC";
PCTSTR p3 = TEXT("ABC");
绾颜 2024-10-07 22:28:38

我认为你很困惑,因为你的函数应该工作得很好:

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中打开“新建项目->C++->CLR控制台”,第一行是:

Console::WriteLine(L"Hello World");

I think you're confused, as your function should work just fine:

int TestFun(LPTSTR lpData)
{
   return  WriteData(lpData); // Should be happy
}

But when you call your function, you'll have to be careful:

TestFun((LPTSTR) L"ABC"); // Will work fine
TestFun((LPTSTR) "ABC");  // Will not work

This is because "ABC" and L"ABC" are two different things. If you look at them in memory:

"ABC"  | 65 66 67 00
L"ABC" | 65 00 66 00 67 00 00 00

Edited to add:

There is nothing like L prefix in .Net

This is just wrong. I just opened "New Project->C++->CLR Console" in VisualStudio, and the first line is:

Console::WriteLine(L"Hello World");
挽梦忆笙歌 2024-10-07 22:28:38

尝试:

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

有关使用 MarshalAsAttribute 进行封送的更多信息,请访问 MSDN。

Try:

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

More information on marshaling with the MarshalAsAttribute on MSDN.

银河中√捞星星 2024-10-07 22:28:38

我会将您的字符串包装在 _T(...) 宏中。这样它就可以在 ANSI 和 UNICODE 版本之间移植。

请注意,您正在使用可移植字符串类型 - LPTSTR - 请注意 T。它将根据构建设置在 ANSI 和 UNICODE 之间变化。

I would wrap your strings in the _T(...) macro. That way its portable between ANSI and UNICODE builds.

Note that you are using the portable string type - LPTSTR - note the T. It will change between ANSI and UNICODE based on build settings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文