我在C ++中有以下结构:
extern "C" __declspec(dllexport) struct SnapRoundingOption
{
double PixelSize;
bool IsISR;
bool IsOutputInteger;
int KdTrees;
};
这是我在C ++中的函数声明:
extern "C" __declspec(dllexport) void FaceGenerationDummy(SnapRoundingOption snapOption);
这是相应的C#代码:
// I also tried not specifying Pack, but the same error occurred.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SnapRoundingOption
{
public double PixelSize;
public bool IsISR;
public bool IsOutputInteger;
public int KdTrees;
public SnapRoundingOption(double pixelSize, bool isISR, bool isOutputInt, int kdTrees)
{
PixelSize = pixelSize;
IsISR = isISR;
IsOutputInteger = isOutputInt;
KdTrees = kdTrees;
}
}
[DllImport("Face.dll")]
public static extern void FaceGenerationDummy(SnapRoundingOption snapRoundingOption);
但是,当我使用此测试调用FaceGenerationDummy
时:
[Test]
public void DummyTest()
{
SimpleInterop.FaceGenerationDummy(new SnapRoundingOption(10, true, false, 1));
}
我发现KdTrees在C ++中是0,而不是传入的。
我做错了什么?
编辑1:我在Windows 7 32位上使用Visual Studio 2008。
编辑2:两个sizeof(SnapRoundingOption)
都返回相同的数字 - 16.
答案 0 :(得分:14)
这里的问题是你如何编组bool
字段。这些是C ++中的单个字节,因此需要编组,因此:
[StructLayout(LayoutKind.Sequential)]
public struct SnapRoundingOption
{
public double PixelSize;
[MarshalAs(UnmanagedType.U1)]
public bool IsISR;
[MarshalAs(UnmanagedType.U1)]
public bool IsOutputInteger;
public int KdTrees;
}
在C ++方面进行匹配:
struct SnapRoundingOption
{
double PixelSize;
bool IsISR;
bool IsOutputInteger;
int KdTrees;
};
我删除了打包设置,以使结构与平台保持自然对齐。
您还应该确保您的通话约定一致。目前看来,C ++代码使用cdecl
,而C#代码使用stdcall
。例如
[DllImport("Face.dll", CallingConvention=CallingConvention.Cdecl)]
将对齐界面的两侧。
答案 1 :(得分:3)
bool
is NOT blittable!它的默认编组是Win32 BOOL
(4个字节),不是 bool
(1个字节)!