gpt4 book ai didi

c# - 将字符串从 .NET 传递到 native (64 位)

转载 作者:行者123 更新时间:2023-11-30 05:39:52 25 4
gpt4 key购买 nike

我在将简单字符串从编译为 64 位的 .NET 应用传递到同样编译为 64 位的 native DLL 时遇到问题。

C++ 签名:

DllExport void SetFoo(LPWSTR foo);

C# 签名:

[DllImport(Library, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal static extern void SetFoo(
[In][MarshalAs(UnmanagedType.LPWStr)] string foo);

然后我在 C# 中运行以下代码:

X.SetFoo("some string");

当它到达DLL中的调试器时,值是用中文骂我:Ⴐ虘翱

当我将 .NET 和 native 代码都更改为 32 位时,我在调试器中获得的值是正确的字符串。我哪里傻了?

作为 Visual Studio 2015 解决方案的最小复制:download here

重现:

  • 使用 WinForms 项目创建新的 Visual Studio 解决方案。
  • 将 DLL 类型的 Win32 项目添加到解决方案
  • 添加以下文件:

Foo.h:

extern "C" {
__declspec( dllexport ) void SetFoo(LPWSTR);
}

Foo.cpp:

#include "stdafx.h"
#include "Foo.h"

DllExport void SetFoo(LPWSTR foo)
{

}
  • SetFoo 中的左大括号上设置断点
  • 在 winforms 窗体中添加一个按钮
  • 双击它,然后调用 SetFoo("abc123")
  • 实现SetFoo:

Form1.cs:

[DllImport("Win32Project1.dll", CallingConvention = CallingConvention.Cdecl,  CharSet = CharSet.Unicode)]
public static extern void SetFoo(string text);
  • 通过打开配置管理器将应用程序更改为以 64 位模式构建。
  • 将 Win32Project1 设置为构建为 x64
  • 将 WindowsFormApplication1 设置为构建为 x64,通过选择新平台,选择 x64,确定。
  • 更改 WindowsFormsApplication1 的输出目录以匹配其他应用程序的输出目录。
  • 无需调试即可开始。
  • 通过将 Attach to 设置为 Managed (v4.5, v4.0) code, Native code 并找到进程来附加调试器 (Ctrl+Alt+P)。
  • 观察断点处的值。

最佳答案

当您将 ANSI 编码的拉丁文本解释为 UTF-16 时,您会看到中文字符。这显然是正在发生的事情。因此,您的 C# 代码正在以某种方式发送 ANSI 编码的文本。

p/invoke 最好这样写:

[DllImport(Library, CallingConvention = CallingConvention.Cdecl, 
CharSet = CharSet.Unicode)]
internal static extern void SetFoo(string foo);

不需要[in],它是默认值。 MarshalAs 毫无意义,因为您指定了 CharSet.Unicode。但是,这两项更改都不会影响语义。

对您在问题中描述的内容的唯一合理解释是:

  • 实际代码与您描述的不一样,或者
  • 调试器存在缺陷。

我建议你把非托管函数改成

DllExport void SetFoo(LPWSTR foo) 
{
MessageBoxW(0, L"", foo, MB_OK);
}

如果消息框显示正确的文本,那么结论似乎是调试器有缺陷。

关于c# - 将字符串从 .NET 传递到 native (64 位),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32067302/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com