C#调用C++ dll时,结构体引用传参的方法

写了一个C++的LogLog Logit 四参数等算法的接口dll,给C#调用,但是发现传参有问题

extern "C" _declspec(dllexport) bool TestFunc(EnumMethod eMethod, unsigned int uiPoints, const double *parA, const double *parB, STRUCTTEST &sTest)

前面的传参非常好解决

枚举本地自定义一个,两个double指针直接ref传参

 double[] rlu = new double[6];
            rlu[0] = 8759;
            rlu[1] = 39686;
            rlu[2] = 108791;
            rlu[3] = 473403;
            rlu[4] = 1679609;
            rlu[5] = 4103842;

            double[] cv = new double[6];
            cv[0] = 0;
            cv[1] = 3;
            cv[2] = 10;
            cv[3] = 50;
            cv[4] = 200;
            cv[5] = 600;
CalculationParm Cparms = new CalculationParm();
 bool rt = Calculation(ArithmeticMethod.Arithmetic_Method_Log_Log,
                6, ref cv[0], ref rlu[0], Cparms);

  直接传参,结果结果并没有根据实际情况变更.

根据相关资料,

在C/C++中,struct类型中的成员的一旦声明,则实例中成员在内存中的布局(Layout)顺序就定下来了,即与成员声明的顺序相同,并且在默认情况下总是按照结构中占用空间最大的成员进行对齐(Align);

然而在.net托管环境中,CLR提供了更自由的方式来控制struct中Layout:我们可以在定义struct时,在struct上运用StructLayoutAttribute特性来控制成员的内存布局。默认情况下,struct实例中的字段在栈上的布局(Layout)顺序与声明中的顺序相同,即在struct上运用[StructLayoutAttribute(LayoutKind.Sequential)]特性,这样做的原因是结构常用于和非托管代码交互的情形。如果我们正在创建一个与非托管代码没有任何互操作的struct类型,我们很可能希望改变C#编译器的这种默认规则,因此LayoutKind除了Sequential成员之外,还有两个成员Auto和Explicit,给StructLayoutAttribute传入LayoutKind.Auto可以让CLR按照自己选择的最优方式来排列实例中的字段;传入LayoutKind.Explicit可以使字段按照我们的在字段上设定的FieldOffset来更灵活的设置字段排序方式,但这种方式也挺危险的,如果设置错误后果将会比较严重。

因此,把结构体显示的声明为 [StructLayout(LayoutKind.Sequential)]即可.

默认(LayoutKind.Sequential)情况下,CLR对struct的Layout的处理方法与C/C++中默认的处理方式相同,即按照结构中占用空间最大的成员进行对齐(Align);

使用LayoutKind.Explicit的情况下,CLR不对结构体进行任何内存对齐(Align),而且我们要小心就是FieldOffset;

使用LayoutKind.Auto的情况下,CLR会对结构体中的字段顺序进行调整,使实例占有尽可能少的内存,并进行

4byte的内存对齐(Align)。

但似乎在vs2005中,默认并不是sequential而是auto