【发布时间】:2013-09-29 19:52:18
【问题描述】:
关注PInvoke byte array to char not behaving properly in 64 bit。 (陈旧的问题和我的怀疑是错误的,因此标题和描述不合适)。
我正在使用 P/Invoke 从 C# 调用 C++ 代码。我在 VS 的构建配置中将 C# 和 C++ 项目设置为在 x64 中构建。当我运行这个程序时,P/Invoke 调用的参数被移动了 32 位,如下所示
C# : |Parameter 1|Parameter 2|Parameter 3|Parameter 4|
| | | | |
V V V V V
C++: |Parameter 1|Parameter 2|Parameter 3|Parameter 4|
所以如果我从 C# 端传递 1,2,3,4,C++ 端会收到 2,3,4,garbage。
我通过在 C# 参数前面传入一个额外的 int 而不更改 C++ 端来解决这个问题。这会将参数偏移 32 位并重新对齐它们,程序可以完美运行。
有谁知道导致这种奇怪偏移的原因以及纠正它的正确方法吗?
这是一个显示我的方法签名的简化示例
C#端:
[DllImport(@"C:\FullPath\CppCode.dll", EntryPoint = "MethodName",
CallingConvention = CallingConvention.Cdecl))]
private static extern bool MethodName(parameters);
C++ 方面:
extern "C" __declspec(dllexport)
bool CppClass::MethodName(parameters)
我怀疑由于参数偏离了 32 位,因此可能有些事情并没有真正在 64 位中正确完成。也许在调用方法时,在变量之前传递了一个隐式指针?如果这只是 C# 端的一个 32 位指针,而 C++ 期望一个 64 位指针,那可能会导致这种偏移情况,但我不确定。
【问题讨论】:
-
您不应显示简化版本。魔鬼在于细节:-)。另外,MethodName 不应该是 C++ 类实例方法,而是类 C 函数。
-
那么应该是静态方法吗?还是我应该把它从课堂上分离出来?
-
static 我猜应该可以工作,这是因为当有人调用该方法时,第一个参数是指向类实例的指针,所以你需要摆脱它。
-
使其成为静态工作。谢谢西蒙!如果您想重新发布您的评论作为答案,我会接受。
-
我相信我在最后一个问题上告诉了你这一切!
标签: pointers 64-bit pinvoke 32bit-64bit