将结构从C#传递到C++;

将结构从C#传递到C++;,c#,c++,interop,C#,C++,Interop,我在C++中有以下结构: extern "C" __declspec(dllexport) struct SnapRoundingOption { double PixelSize; bool IsISR; bool IsOutputInteger; int KdTrees; }; 这是我在C++中的函数声明: extern "C" __declspec(dllexport) void FaceGenerationDummy(SnapRoundingOption

我在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#代码:

但是,当我使用此测试调用
FaceGenerationDummy
时:

[Test]
public void DummyTest()
{
    SimpleInterop.FaceGenerationDummy(new SnapRoundingOption(10, true, false, 1));
}
< >我发现C++中的kd树是0,而不是1。 我做错了什么

编辑1:我正在Windows 7 32位上使用Visual Studio 2008


编辑2:两个
sizeof(SnapRoundingOption)
返回相同的数字–16

这里的问题是如何编组
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>,C代码使用<代码> STDCALL> /COD>。比如说

[DllImport("Face.dll", CallingConvention=CallingConvention.Cdecl)]

将对齐界面的两侧。

!它的默认封送是Win32
BOOL
(4字节),而不是
BOOL
(1字节)

你确信C++中的包装对齐也是1吗?我试过了,指定<代码>包>代码>,不指定<代码>包>代码>,没有一个有效。@ GrimeTon:还有,你的C++编译器认为<代码> int >代码是32位宽吗?你的
struct
的单词“struct”在哪里?那是打字错误还是你写的东西?!在C++中检查你的结构的内存表示,使用适当的<代码>包>代码>代码> MalSalase<代码>属性/参数。@谢谢你,我喜欢这些P/调用问题!大卫:同上。。。他们让我更难思考(我特别喜欢COM接口问题……那些可能真的很棘手!)@威顿,为什么你也不做C++部分?这很重要!无论如何,我为此编写了一个测试,并成功地将这个结构从两个方向传递过来。@戴维:这就是我在40分钟前在我的评论中提出的建议:-P@ @ Grimt:在C++和C语言中,打包对齐应该是相同的。它应该与Pack=0一起工作,或者不与Pack=0一起工作。@David:您确定WinAPI使用packing-alignment 1吗?MS建议使用默认打包(8),以便数据类型根据其大小进行对齐。另外,我只看到MS对数组使用pack=1(内部生成)@引力子:+1:既然你陈述了布尔的目的(大卫·赫弗南在回答中忘记了这一点:-))
[DllImport("Face.dll", CallingConvention=CallingConvention.Cdecl)]