从c+传递数组+;到c#并通过值或引用返回,哪一个更好,为什么?

从c+传递数组+;到c#并通过值或引用返回,哪一个更好,为什么?,c#,c++,arrays,pointers,C#,C++,Arrays,Pointers,我已经遵循了类似于一条线索的建议 如何将C++中的值数组传递给C语言。@CodyGray对我最近提出的为什么要使用指针的问题发表了评论之后,我尝试在没有指针和封送处理代码的情况下传递值,同样遵循 而且它也有效!我很困惑,正确/最好的方法是什么?为什么在这里使用指针 下面是一些代码: 考虑导出的C++函数 extern "C" { __declspec(dllexport) void PointerTest(char ** text, float* fArray, int * iArray); }

我已经遵循了类似于一条线索的建议 如何将C++中的值数组传递给C语言。@CodyGray对我最近提出的为什么要使用指针的问题发表了评论之后,我尝试在没有指针和封送处理代码的情况下传递值,同样遵循
而且它也有效!我很困惑,正确/最好的方法是什么?为什么在这里使用指针

下面是一些代码:

考虑导出的C++函数

extern "C" { __declspec(dllexport) void PointerTest(char ** text, float* fArray, int * iArray); }
以下是我在c#所做的事情:

<>这是从C到C++传递值的好方法;但是,使用我找到的指针返回值(可靠)的唯一方法是函数的返回值,这导致我将所有类型的值填充到一个大数组中并返回(再次通过引用)

现在考虑这个代码:

[System.Runtime.InteropServices.DllImport("myTest.dll")]
        private static extern void PointerTest([In, Out] String text, [In, Out] float[] fArray, [In, Out] int[] iArray);

public void DoSomething(String text, float[] F, int[] I){   
            PointerTest(text, F, I);
            }
据我所知,这也是一样的。另外,通过使用[In,Out]语义,我可以在调用PointerTest后轻松访问修改后的数组

现在我错过了什么?显然,对于像我这样的初学者来说,第二种方法更干净、更容易理解,而且网上的标准答案仍然是使用指针/第一种方法……这让我得出结论,第二种方法肯定有问题,但后来我从msdn得到了答案


请帮助我理解这一点。提前感谢。

我对C++/C#interop几乎一无所知,但根据(参见有关封送的部分),选择[in,Out]还是指针应该基于封送的需要。“通过将参数和字段声明为IntPtr,”文档中说,“您可以提高性能,尽管这是以易用性、类型安全性和可维护性为代价的。”文档还说,“小心使用[in]和[out]属性,以减少不必要的封送。”


我对文档的超简短浏览向我表明,[输入,输出]和指针都可以工作。看来首先要考虑的是性能。对于您正在处理的数据,上述两种方法是否都具有足够的性能?如果是这样的话,最好按照你的建议选择更干净、更容易理解的。但别相信我的话,看看吧!(文档,即,

)<代码> c>代码>与此有关吗?C++ DLL是如何构建的?也就是说,使用了什么调用约定(
stdcall
cdecl
,等等)?C的默认值是代码> STDCALL> /CODE >,但是如果C++的DLL使用了代码< > CDECL < /C> >(即编译<代码> /GD< /COD>),则需要使用<代码> dLimPult >,像这样的代码> [DLimPurt(DLLNAMEL,CalpCngult= CalpCngultC.DCDL)] < /C>调用约定改变了堆栈的清理方式(调用者/被调用者),这可能会影响您封送代码的方式。感谢您清除了这一点……它是用/Gd构建的,我现在将/Gd改为stdcall,并保留了c#原样。有趣的是,这个错误并没有导致错误…啊哈…我可以看出传递地址而不是数据本身可以更快-atm我处理的数据量相当小,所以我无法区分。。。。谢谢你的链接,很多好信息!
[System.Runtime.InteropServices.DllImport("myTest.dll")]
        private static extern void PointerTest([In, Out] String text, [In, Out] float[] fArray, [In, Out] int[] iArray);

public void DoSomething(String text, float[] F, int[] I){   
            PointerTest(text, F, I);
            }