1

我从 C# 调用 C++ 代码,通过字节数组作为参数传递。此 C++ 代码会发生几何冲突,当我以 32 位编译所有内容时,它的行为正常。当我以 64 位编译所有内容时,我会得到有时正确有时不正确的零星行为。

C# 方面:

[DllImport(@"C:\FullPath\CppCode.dll", EntryPoint = "GeomCompare")]
private static extern bool GeomCompare(byte[] data1, byte[] data2);

C++ 方面:

extern "C" __declspec(dllexport)
bool CppClass::GeomCompare(unsigned char *data1, unsigned char *data2)

在 64 位中,有时,当我在不同场合从 C# 代码传递相同的 byte[] 时(在 c# 端,byte[] 始终处于相同状态),有时从 C++ 中看到它为 null,有时它读起来就好了。其他时候,当从 byte[] 读取时,C++ 会收到 AccessViolationException。

奇怪的是,当我用 32 位编译这个 DLL 时,它工作得很好。我怀疑 64 位编组可能有些奇怪,但我没有发现任何东西。

编辑:
在使用 4 个整数对虚拟函数进行一些测试后,我发现当它到达 C++ 端时,我的参数在内存中都偏移了 32 位。

例子:

C# : |Parameter 1|Parameter 2|Parameter 3|Parameter 4|
           |           |           |           |           |
           V           V           V           V           V
C++:             |Parameter 1|Parameter 2|Parameter 3|Parameter 4|

似乎所有数据都向下移动了 32 位,因此 C++ 接收参数 2、3、4、垃圾而不是接收参数 1、2、3、4。

我通过在 C# 端的其余参数前面传入一个垃圾整数来解决这个问题,而无需更改 C++ 代码来更正这个 32 位偏移量。这现在可以在从 C# 代码调用时工作。

但是,在我的最终使用中,我必须从 SQL 的 CLR 集成函数中调用此 C# 代码。无论有没有这种解决方法,我都会从 SQL 中获取 AccessViolationExceptions。

4

0 回答 0