P / Invoke - 简单添加struct参数

时间:2012-12-04 11:32:47

标签: c# .net c visual-c++ pinvoke

我有这个C代码:

real_T addition(const struct_T parameters)
{
    return parameters.a + parameters.b;
}

typedef struct
{
    real_T a;
    real_T b;
} struct_T;

typedef double real_T;

我从C#调用它:

using System.Runtime.InteropServices;

    namespace AdditionConsoleApplication
    {
        class Program
        {
            [DllImport(@"X:\Bla\Addition.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern double addition(struct_T parameters);

            static void Main(string[] args)
            {
                struct_T parameters = new struct_T();
                parameters.a = 1;
                parameters.b = 3;

                Console.WriteLine(addition(parameters));
            }
        }
    }

这里是struct_T:

[StructLayout(LayoutKind.Sequential)]
class struct_T
{
    public double a;
    public double b;
}

不幸的是,数学不正确:

2.72645911468311E-284

有人能看错吗?

1 个答案:

答案 0 :(得分:1)

您对结构有这个定义:

[StructLayout(LayoutKind.Sequential)]
class struct_T
{
    public double a;
    public double b;
}

p / invoke marshaller将通过引用封送类。换句话说,指向对象的指针被传递给本机代码。这种不匹配解释了程序失败的原因。

解决方案是确保界面的两侧都匹配。一种方法是在两侧传递。实现这一目标的一种简单方法是将结构声明为C#中的值类型。通过使它成为结构来做到这一点:

[StructLayout(LayoutKind.Sequential)]
struct struct_T
{
    public double a;
    public double b;
}

另一种方式是双方通过引用。您可以通过在C#端使用class并更改C代码来实现此目的。

real_T addition(const struct_T* parameters)
{
    return parameters->a + parameters->b;
}