写了一个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[];
rlu[] = ;
rlu[] = ;
rlu[] = ;
rlu[] = ;
rlu[] = ;
rlu[] = ; double[] cv = new double[];
cv[] = ;
cv[] = ;
cv[] = ;
cv[] = ;
cv[] = ;
cv[] = ;
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