写了一个简单的使用char**输出字符串数组的方法,尝试在C#中调用,
C++的函数声明如下:
extern "C" __declspec(dllexport) int __stdcall Getpp(char** p);
  
以下是在C#中的调用        [DllImport("cppdll")]
        public static extern int Getpp(byte[] str);        static void Main(string[] args)
        {
            string[] strs = new string[2];
            int len = 50;
            byte[] buffer =new byte[len * 2];
            Getpp(buffer);
            for (int i = 0; i < 2; i++)
            {
                strs[i] = Encoding.Default.GetString(buffer, i, len);
                i += len;
            }
        }为什么总是产生异常:“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”?
哪个达人帮帮忙,是不是取出char**输出参数的方式错了?
谢谢

解决方案 »

  1.   

    char** 啊指针的指针……这个问题难哦……
      [DllImport("cppdll")]
            public static extern int Getpp(byte[] str);        static void Main(string[] args)
            {
                string[] strs = new string[2];
                int len = 50;
                object buffer=null;
                Getpp(out buffer);
                string out=(string)(string )buffer;
                for (int i = 0; i < 2; i++)
                {
                    strs[i] = Encoding.Default.GetString(buffer, i, len);
                    i += len;
                }
            }
    你试试我页不知道对不对 没遇到过**的转换
      

  2.   


       unsafe class Program
        {
            [DllImport("cppdll.dll")]
            public static extern int Getpp(byte** p);
            static void Main(string[] args)
            {
                byte* str = stackalloc byte[100];
                int temp = Getpp(&str);
                byte[] tempstr = new byte[100];
                for (int i = 0; i < temp; i++)
                {
                    tempstr[i] = str[i];
                }            Console.WriteLine(System.Text.ASCIIEncoding.ASCII.GetString(tempstr));
            }
        }
      

  3.   

    晕啊,指针的指针,还好是只是对象和结构的指针
    记忆中似乎是这个东西Marshal.PtrToStructure
    IntPtr   v;   
      IntPtr   pv;   
      YourStruct   obj;   
      Marshal.PtrToStructure(v,   pv);   
      Marshal.PtrToStructure(pv,   obj);如果是函数的指针那就头痛了,那个堆上,不容易搞到
      

  4.   

    谢谢两位的回答
    参数前加上out我有试过,会变成只得到字符串的第一个字符。
    试了楼上的朋友说的方法,稍微改了改可以读取第一个字符串,但是char**指向的其他字符串如何读呢?
    我在Getpp(**p)中的方法定义如下:
    int __stdcall Getpp(char** p)
    {
    strcpy(p[0],"string1");
    strcpy(p[1],"string2");
    return 2;
    }
    我是不是应该在unsafe的C#环境里头定义一个非托管的二维数组传入?我尝试使用如下的代码创建一个byte*的数组,但是有语法错误            byte** strings = stackalloc byte*[2];
                strings[0] = stackalloc byte[100];
                strings[1] = stackalloc byte[100];
    请问如何定义才是正确的呢?
      

  5.   

    楼上的大大可以不可以具体些呢?Intptr如何指向一个二维数组
      

  6.   

    byte[][]~?指针形式的字符串API调起来是n麻烦.....
      

  7.   


    byte** strings;
    strings[0] = stackalloc byte[100];
    strings[1] = stackalloc byte[100];
       
    只是一个内存块 我只是把内存放在堆栈上
    比放在堆上好多了     
      

  8.   

    [DllImport("cppdll")]
    public static extern int Getpp(out IntPtr lpStr);
      

  9.   

    还是不行。。语法错误,编译都过不了
    lpStr 应该怎样取得比较好?Marshal.StringToPtrANSI应该只能转换一个字符串吧?
    如果要定义一个lpStr的数组的话,如何再次得到一次IntPtr?而且函数调用之后怎么转换回来?还请大大们指导指导~~
      

  10.   

     IntPtr intptr;
    Getpp(out intptr);
                           
    出现错误:“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”? 
      

  11.   


    [DllImport("cppdll")]
            public static extern int Getpp(StringBuilder str);        static void Main(string[] args)
            {
                StringBuilder strs = new StringBuilder("");
                Getpp(strs);
           }
      

  12.   

    强。STRINGBUILDER可以。我试了的。