小弟最近做一个项目,需要c#调用第三方的DLL,但是DLL接口是我来定,Dll里面的算法具体别人实现。DLL接口暂定如下:
ANALYZEPLANES_API int _stdcall GetCalculateResults(double measureVar[],int PlanesID[],double holeAngle[],double holeDepths[])
 {
 }
其measureVar[]数组长度是确定的为4,别人拿到这个数组之后,在算法中用其中的数据进行计算。利用接口的其它数组返回计算结果,问题在于计算的数据最终长度不确定,因此我在c#端调用时传递实参数组时不知道应该传多长的数组。当然我想到一个比较笨的方法。是在c#端传递足够长的实参数组,但总觉得这种方法不好。所以想请教各位高手,能不能有好的方法解决这个问题。

解决方案 »

  1.   

    这个dll方法有很大的问题
      

  2.   

    那请问hdt,应该怎样改进方法了?能否给予一点建议。谢谢
      

  3.   

    "题在于计算的数据最终长度不确定,因此我在c#端调用时传递实参数组时不知道应该传多长的数组",
    楼主,你定义的C++接口有问题,改成:ANALYZEPLANES_API int _stdcall GetCalculateResults(double measureVar[],int measureSize,int PlanesID[],int planeSize,double holeAngle[],int angleSize,double holeDepths[],int depthSize);你必须明确告诉net这边数组大小,否则它没法正确分配空间,就更谈不上正确传递参数!
      

  4.   

    简化一下楼主的要求 
    //a 输出参数,可能会改变长度
    void test(char[] a)
    {
       //因为是输出参数,且会改变长度,而一段已分配的地址,无法随便改变长度
       //所以
       a = remalloc(....);
       strcpy(a,"......");
       
    }
    //请问可以改变吗???
      

  5.   

    如果每次调用时数组长度的差异很大,不妨这样,dll中写一个被调用函数,一个函数指针,被调用函数在堆中分配空间,完事后调用函数指针所指向的调用方函数,传递地址和长度,调用方拷贝处理数据返回,dll中函数指针执行完毕之后释放堆内存。
    第二种方法就是dll中写两个函数,一个被调用时在堆中分配空间并返回地址和长度,一个函数释放堆内存空间。调用方调用完第一个函数并直接处理数据后,调用第二个函数释放内存。
      

  6.   

    不知道大家想想没有,无论是数据的传入,或从C++传出,程序执行时,,调用者在执行时肯定是知道数组具体的的长度,就如我们如一个图片操作一样,你在执行是肯定时可以知道具体的大小空间!对于平台调用,数组参数的封送,是有具体的方向属性,如果什么都不写,默认为[In]属性,参数是不会回传的,所以7楼举的例子是错误的,当然,对于直接拷贝的类型例外(即值类型,它会直接改变内存地址的值!而char对于CLR顶层来说非bittlte类型)!所以,对于数组参数,对于net来说,同时要做输入和输出,要显示加上方向属性[In,out],或者outhdt,这位兄弟,如果你想在互操作问题共同探讨,我很高兴,大家一起进步!
      

  7.   

    当然lizhibin1的方法是肯定是可以的,但是我是想尽可能在接口数量少的情况下去实现我要求的功能,希望各位继续能帮我出主意。
      

  8.   

    可以返回 IntPtr 类型的值代表数组的地址,以及一个整数值代表数组的大小。然后使用 Marshal.Copy 来将数据装到你根据c++ dll返回的大小而实例化的数组中。