c# - C++ DLL LPCTSTR 到 C# 字符串

标签 c# c++ dll

我正在尝试将字符串从 C++ DLL 获取到 C#。 它输出不正确的符号 - {栠搂犯获긋泳赠琹玴ɡ鳌⻜}

这是我的代码: C++动态链接库

_declspec(dllexport) int __stdcall myClass(LPCTSTR& z)
{
    z = _T("Test String");
    return 0;
}

我的C#代码读取C++ DLL:

[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern void myClass(StringBuilder z);

static void Main(string[] args)
{
    StringBuilder z = new StringBuilder();
    myClass(z);
}

最佳答案

首先,确保您在 C++ 中定义了 UNICODE 宏,以便 _T 输出 wchar_t 数据,以及 LPCTSTR 表示 const wchar_t*。这就是 CharSet.Unicode 所期望的。顺便说一下,如果你不打算也支持 ANSI 版本,我不会为所有这些 _T 的东西而烦恼,只是在任何地方都使用 Unicode,代码会更简单。

此外,您的 C++ 函数返回一个 int,但您的 C# 函数需要一个 void。你在那里不匹配(除非你打算将 PreserveSig 设置为 false)。

在 C# 端,当您提供 StringBuilder 时,这意味着您向 C++ 端提供了一个缓冲区,并且您希望它填充该缓冲区。正确的用法应该是这样的:

_declspec(dllexport) int __stdcall myClass(LPCTSTR z, int zSize)
{
    _tcscpy_s(z, zSize, _T("Test String"));
    return 0;
}
[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern int myClass(StringBuilder z, int zSize);

static void Main(string[] args)
{
    StringBuilder z = new StringBuilder(256);
    myClass(z, z.Capacity);
}

但是您的代码返回一个指向静态字符串的指针,这是编码器在这里不期望的。

如果你想保持你的 C++ 代码不变,你可以试试这个:

[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern int myClass(out string z);

static void Main(string[] args)
{
    string z;
    myClass(out z);
}

我承认我没有测试它,但它应该可以工作,因为这个 C# 签名与 C++ 签名匹配。

如果一切都失败了,你可以尝试自己编码数据:

[DllImport("ecrClassDll.dll")]
static extern unsafe int myClass(void** z);

static unsafe void Main(string[] args)
{
    void* z;
    myClass(&z);
    var str = Marshal.PtrToStringUni(new IntPtr(z));
}

关于c# - C++ DLL LPCTSTR 到 C# 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34262991/

相关文章:

c++ - 链接方法导致数据损坏

c - 在 gdb 上,LoadLibrary 满足 sti 指令并发出 SIGILL 信号

永远不应返回 null 的 List 属性的 C# 快捷方式

c# - 升级到 Android 9 后无法从 Xamarin.Forms 应用程序打开 ESP32 套接字

c++ - C++ 中的静态 unordered_map 指针初始化

c++ - 一位读者。一位作家。关于互斥量和原子内置函数的一些一般性问题

c# - TPL 数据流转换 block 并行发布到两个操作 block

c# - 检查 dateTime 是周末还是工作日

c# - 将多个 .NET 二进制文件合并在一起?

c++ - 让 DLL 而不是应用程序崩溃