[英]Passing string from .NET to native (64-bit)
I am having an issue passing a simple string from my .NET app, compiled as 64-bit, to my native DLL, also compiled as 64-bit. 我在将一个简单的字符串从我的.NET应用程序(编译为64位)传递到我的本机DLL(也编译为64位)时遇到问题。
C++ signature: C ++签名:
DllExport void SetFoo(LPWSTR foo);
C# signature: C#签名:
[DllImport(Library, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal static extern void SetFoo(
[In][MarshalAs(UnmanagedType.LPWStr)] string foo);
Then I run the following code in C#: 然后,我在C#中运行以下代码:
X.SetFoo("some string");
When it reaches the debugger in the DLL, the value is swearing at me in Chinese: Ⴐ虘翺
当它到达DLL中的调试器,该值在我在中国宣誓:
Ⴐ虘翺
When I change both the .NET and native code to 32-bit, the value I get in the debugger is the correct string. 当我将.NET和本机代码都更改为32位时,我在调试器中获得的值是正确的字符串。 Where am I being stupid?
我在哪里傻?
Minimal reproduction as a Visual Studio 2015 Solution: download here 作为Visual Studio 2015解决方案的最小复制: 在此处下载
To reproduce: 复制:
Foo.h: foo.h中:
extern "C" {
__declspec( dllexport ) void SetFoo(LPWSTR);
}
Foo.cpp: Foo.cpp中:
#include "stdafx.h"
#include "Foo.h"
DllExport void SetFoo(LPWSTR foo)
{
}
SetFoo
SetFoo
括号中设置断点 SetFoo("abc123")
. SetFoo("abc123")
。 SetFoo
: SetFoo
: Form1.cs: Form1.cs中:
[DllImport("Win32Project1.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern void SetFoo(string text);
Attach to
to Managed (v4.5, v4.0) code, Native code
and finding the process. Attach to
到Managed (v4.5, v4.0) code, Native code
并找到进程Attach to
附加调试器(Ctrl + Alt + P)。 When you interpret ANSI encoded latin text as UTF-16 you see Chinese characters. 当您将ANSI编码的拉丁文解释为UTF-16时,会看到中文字符。 That's clearly what is happening.
显然这是正在发生的事情。 So your C# code is sending ANSI encoded text somehow.
因此,您的C#代码以某种方式发送ANSI编码的文本。
The p/invoke would be better written like this: p / invoke最好这样写:
[DllImport(Library, CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode)]
internal static extern void SetFoo(string foo);
The [in]
is not needed, it is the default. 不需要
[in]
,它是默认值。 And the MarshalAs
is pointless since you specified CharSet.Unicode
. 并且
MarshalAs
是没有意义的,因为您指定了CharSet.Unicode
。 However, neither change affects the semantics. 但是,这两个更改都不会影响语义。
The only sound explanations for what you describe in the question are: 您在问题中所描述的唯一合理的解释是:
I suggest that you change the unmanaged function to 我建议您将非托管功能更改为
DllExport void SetFoo(LPWSTR foo)
{
MessageBoxW(0, L"", foo, MB_OK);
}
If the message box displays the correct text then the conclusion would appear to be that the debugger is defective. 如果消息框显示正确的文本,则结论是调试器有缺陷。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.