1

我有这个 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

有人能看出什么不对吗?

4

1 回答 1

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;
}

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

real_T addition(const struct_T* parameters)
{
    return parameters->a + parameters->b;
}
于 2012-12-04T15:57:47.780 回答