我有这个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
有人能看错吗?
答案 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;
}