将字符串从.net传递到本机(64位)
Passing string from .NET to native (64-bit)
我遇到了一个问题,从我的。net应用程序传递一个简单的字符串,编译为64位,到我的本机DLL,也编译为64位。
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和本机代码都更改为32位时,我在调试器中得到的值是正确的字符串。我在哪里犯傻了?
最小化复制作为Visual Studio 2015解决方案:在这里下载
复制:
- 用WinForms项目创建一个新的Visual Studio解决方案。
- 在解决方案中添加一个DLL类型的Win32项目
- 添加以下文件:
foo:
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, OK。
- 将WindowsFormsApplication1的输出目录更改为与其他应用程序的输出目录匹配。
- 不调试启动。
- 附加调试器(Ctrl+Alt+P)通过设置
Attach to
为Managed (v4.5, v4.0) code, Native code
并找到进程。 - 观察断点处的值
当您将ANSI编码的拉丁文本解释为UTF-16时,您将看到中文字符。这显然是正在发生的事情。所以你的c#代码以某种方式发送ANSI编码文本。
p/调用最好这样写:
[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++本机插件更新Vector3数组
- GCC本机矩阵运算库
- VC++本机单元测试,找不到调试符号
- 将应用程序从32位移植到64位时出现问题
- 64位机器上的C++内存对齐
- 在这种情况下,java对象是否可以调用本机函数
- PC中的程序和PHONE中的本机描述应用程序之间的数据连接
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- qmake:检测目标位宽(32 位或 64 位)
- 如何在 64 位 vb.net Windows 应用程序中引用 32 位 dll
- Qt 5.11.2 (Clang 8.0 (Apple), 64 位), 找不到 QJSEngine 文件
- 无法将标准库导入本机 android 项目中的头文件
- 在 64 位边界上对齐C++结构数组?
- 如何为字符串生成唯一但一致的 N 位哈希(小于 64 位)?
- 从命令行运行本机 VS2012/C++ 64 位单元测试
- 如何在Visual C++中编写本机64位代码
- 如何在64位Windows 7上使用cygwin从c++生成Java虚拟机
- 位图按位操作的位集或本机数据类型
- 将字符串从.net传递到本机(64位)
- 在64位环境中加载本机COM dll