各位达人,小弟最近编程时要用到一用VC6写的DLL,其中有一个接口不知该如何调用,其原型如下:void WordSegment_dll(void* pSegger, char* str, char** pWord, int& wordNum);偶知道C#中可以将void*转化成IntPtr,char*转化成StringBuilder,int&转化成out int。~~但是~~,char**我不会转化。:(
我在C#中这样对上面的char** pWord参数处理:(这里的char** pWord在DLL中是一个N*N的数组。)ArrayList pWord = new ArrayList(N);
for (int i = 0; i < N; i++)
{
pWord.Add(new char[N]);
}然后将C#中的声明写为:[DllImport("IRLAS.dll")]
public static extern void WordSegment_dll(IntPtr pSegger, string line, ArrayList pWord, out int wordNum);编译可以通过,但运行时会抛出AccessViolationException异常:“受保护的内存被破坏”。我觉得这样的类型转换可能有问题,但不知道应该怎么写。请达人们指教!
小弟跪谢!

解决方案 »

  1.   

    请高手们帮帮忙~~C++中的char**应该转换成C#中的什么类型?
      

  2.   

    char*=string
    char* = string * 
    呵呵,可以实验一下
      

  3.   

    个人看法
    char *p 中的p是一个指针 一个4字节的uint 这个地址是一连串Char的开始位置char **p 的p也是一个指针 这个地址是一个N*N的 char的矩阵的开始地址
    在内存中的情况 应该是一个N*N个连续的char 
    也就是说可以 把p看成是一个 有N*N个char 的一维char数组的开始地址
    我认为转成IntPtr应该也可以然后用 
    Marshal.Copy 方法 (IntPtr, Char[], Int32, Int32)
    将数据从非托管内存指针复制到托管字符数组。
    source
    内存指针,从中进行复制。 destination
    要复制到的数组。 startIndex
    数组中 Copy 开始位置的从零开始的索引。 length
    要复制的数组元素的数目。
      

  4.   

    上面的不对应该是在C#中有一个IntPtr
    然后用Marshal.AllocHGlobal (Int32) 
    使用 GlobalAlloc 从进程的非托管内存中分配内存。 
    再用
    Marshal.Copy (Char[], Int32, IntPtr, Int32)  
    将数据从一维的托管字符数组复制到非托管内存指针 (把那个N*N看成是一维的)
    最后将这个IntPtr传给你的函数以上仅是我的计想 没做过 你试试看 希望对你有帮助
      

  5.   

    To jimgreat:谢谢~~
    不过问题依然如故~~AccessViolationException
      

  6.   

    To jimgreat:用您的第二种方法,抛出的异常是System.StackOverflowException:未处理的“System.StackOverflowException”类型的异常出现在 mscorlib.dll 中。百思不得其解~~55~~
      

  7.   

    另:这个DLL不是我做的,我也不知道源码~~不过我拿到它时,同时拿到了一个在C++程序中调用的示例,在这个例子中是这么对char** pWord处理的:char** pWord = new char*[N];
    for (int i = 0; i < len; i++)
    {
    pWord[i] = new char[N];
    }这么说来pWord应该是一个字符指针的数组,而不是字符的二维数组。
      

  8.   

    IntPtr pWord = new IntPtr[N];
    for (int i = 0; i < len; i++)
    {
    pWord[i] = Marshal.AllocHGlobal (N); 
    }
    试一试
      

  9.   

    [DllImport("IRLAS.dll")]
    public static extern void WordSegment_dll(IntPtr pSegger, string line, string[] pWord, out int wordNum);
    是不是这样的?
      

  10.   

    To jimgreat:IntPtr pWord = new IntPtr[N];
    for (int i = 0; i < N; i++)
    {
    pWord[i] = Marshal.AllocHGlobal (N);
    }这个没抛出异常,但……我不知道怎么把它转化回来呢?
    我用的方法是
    Marshal.Copy(pWord[0], destArray, 0, N); (第0组)
    但结果不对。
    这里面是不是有编码转化的问题?C#的默认编码是Unicode,而我用的DLL的编码可能是微软的MBCS。
    该死……
      

  11.   

    找到答案了// 转换第0组
    byte[] destArray = new byte[N];
    Marshal.Copy(pWord[0], destArray, 0, N);
    string destString = Encoding.GetEncoding("GB2312").GetString(destArray);
    destString = destString.Remove(destString.IndexOf('\0'));这就全对了~~
    弄了一个月,终于弄出来了~~555~~~谢谢jimgreat大侠!感激之情难以言述~~所以,就用分数表达吧~~