将结构从C#传递给C++

Gra*_*ton 9 c# c++ interop

我在C++中有以下结构:

extern "C" __declspec(dllexport) struct SnapRoundingOption
{
    double PixelSize;
    bool IsISR;
    bool IsOutputInteger;
    int KdTrees;
};
Run Code Online (Sandbox Code Playgroud)

这是我在C++中的函数声明:

extern "C" __declspec(dllexport) void FaceGenerationDummy(SnapRoundingOption snapOption);
Run Code Online (Sandbox Code Playgroud)

这是相应的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);
Run Code Online (Sandbox Code Playgroud)

但是,当我打电话给FaceGenerationDummy这个测试时:

[Test]
public void DummyTest()
{
    SimpleInterop.FaceGenerationDummy(new SnapRoundingOption(10, true, false, 1));
}
Run Code Online (Sandbox Code Playgroud)

我发现KdTrees在C++中为0,而不是传入的1.

我究竟做错了什么?

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

编辑2:两者都sizeof(SnapRoundingOption)返回相同的数字 - 16.

Dav*_*nan 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;
}
Run Code Online (Sandbox Code Playgroud)

在C++方面匹配这个:

struct SnapRoundingOption
{
    double PixelSize;
    bool IsISR;
    bool IsOutputInteger;
    int KdTrees;
};
Run Code Online (Sandbox Code Playgroud)

我删除了包装设置,以便结构对齐平台自然.

您还应该确保您的呼叫约定一致.就目前而言,它看起来像C++代码使用cdecl,而C#代码使用stdcall.例如

[DllImport("Face.dll", CallingConvention=CallingConvention.Cdecl)]
Run Code Online (Sandbox Code Playgroud)

将对齐界面的两侧.

  • @David:你确定使用打包对齐1的WinAPI吗?MS建议使用默认打包(8),以便根据数据类型调整数据类型.另外,我只看到MS使用pack = 1作为数组(内部生成)... @Graviton:http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx (2认同)

Meh*_*dad 5

bool不可位块传输!它的默认封送处理是 Win32 BOOL(4 字节),而不是 bool(1 字节)!