在C#项目中有个功能是需要调用一个C++写的DLL(test.dll)里面有个函数原型是:
void ConverseTriangleA(double a[][3], int size,double (*pp)[3][3],int *num);我在C#中调用代码如下:
public class CallCppDll
    {
        //导入DLL
        [DllImport("test.dll", EntryPoint = "ConverseTriangleA", CharSet = CharSet.Auto)]
        public static extern void ConverseTriangleA(double[,] m_adX, int size, double[, ,] TriangleALL, ref int num);
    }......//几个三维的点用之前已经赋值了
double[,] _m_adX = new double[,] { { x1, y1, z1 }, { x2, y2, z2 }, { x3, y3, z3 }, { x4, y4, z4 } };
//点的个数
int count = 4;
//三维数组用来接收算法运算完之后的点的集合
double[, ,] TriangleALL = new double[500, 3, 3];
//集合的个数
int sum=0;调用函数
CallCppDll.ConverseTriangleA(_m_adX, count, TriangleALL, ref sum);...
根据TriangleALL的值和sum的值来进行操作.
问题:通过上诉代码我在调用第一次时,程序运行正常,可是如果我连续调用(使用按钮,多次点击按钮)时,就会出现:
尝试读取或写入受保护的内存。这通常指其他内存已损坏。请问大家这是什么原因造成的?为什么第一次就行,第二次就不行了呢?是资源没有释放吗?还是。。

解决方案 »

  1.   

    我不知道是不是C++动态库的问题,还是我自己C#代码的问题,不是CLR只能自动释放托管代码的资源吗?
    但是对非托管代码不是需要我们手动来释放的吗?我是不是需要手动释放资源?谢谢。
      

  2.   

     手动释放资源也只能在C++ DLL里面代码释放吧,C#你如何释放C++里的资源呢。
      

  3.   

    //三维数组用来接收算法运算完之后的点的集合
    double[, ,] TriangleALL = new double[500, 3, 3];
    是用来接收数据的吗?是不是要用ref
      

  4.   


    dllimport
    指定调用约定, 你的好像是 cdecl
      

  5.   

    如果你自己有C++代码,建议通过C++/CLI封装调用,而不是通过PInvoke调用.
    通过C++/CLI你可以直接调试C++代码.
      

  6.   


    好像后面是啥玩意?
    如果使用PInvoke调用程序改怎么处理?double (*)pp[3][3] 不就是double[,,] pp吗 应该不需要ref关键字
      

  7.   

    C++的多维数组,在C#这边转成一维数组处理,请看一下下面这个帖子我的回复
    C#调用C++ DLL(结构体中二维数组转换)
      

  8.   

    根据个人理解:
    ConverseTriangleA(double a[][3], int size,double (*pp)[3][3],int *num);
    中double (*pp)[3][3],int *num在DLL中是没有分配内存空间的,也不会处理垃圾回收等工作
    需要我在C#中创建内存区域通过参数传递进去,然后DLL会把我创建内存区域填充数据,而我在通过
    填充的数据进行操作。
      

  9.   

    同样的操作同样的代码,结果怎么不一样呢?
    在C#代码中开辟一段内存区域,通过调用C++ DLL的算法来填充这段内存区域,然后在C#代码中取出这段内存区域的数据进行操作。。为什么第一次运行时无误,重复操作时就出现问题了呢?不都是这样的一个过程开辟内存区域,填充区域,然后取出内存区域的数据的过程。。我现在很怀疑是在第二次填充内存区域时出错的。。但是不知道怎么确定?