我C++编写了一个返回字符串的函数 返回值为char*类型
用C#调用的时候就出现“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”的错误(AccessViolationException)char *a = new char[PA->P_ANALYSIS("i+i*i#").length()+1];
strcpy(a,PA->P_ANALYSIS("i+i*i#").c_str());
return a;[DllImport("GRAMMAR_ANALYSIS.dll", EntryPoint = "dll_output", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern string dll_output();
我已经看了网上很多方法了  C++代码自己运行肯定没问题 我已经测试过 a在C++中的返回值正确  就是一转到C#中的时候报错

解决方案 »

  1.   


    extern "C" _declspec(dllexport)  char* dll_output(){
    Ap *PA = new Ap("A::A+C|C",P);//ICON = 3
    Ap *PC = new Ap("C::C*E|E",P);//ICON =2
    Ap *PE = new Ap("E::(A)|i",P);//ICON=3
    PA->setNEXTP(PC);
    PC->setNEXTP(PE);
    //Ap* ptr = new Ap();
    //ptr = readfile("test1.txt"); PA->leftcircle_CHECK();
    //PA->print_allp(); PA->setFIRST();
    PA->setFOLLOW();

    cout<<"\n\n\n\n\n"<<"================================="<<endl
          <<"所输入的字符串产生顺序为:"<<endl;

    char *a = new char[PA->P_ANALYSIS("i+i*i#").length()+1];
    strcpy(a,PA->P_ANALYSIS("i+i*i#").c_str());
    return a;


    }
      

  2.   

    改过了 没有用啊
    而且我返回的事char* 在C#对应的应该是STRING 
    改了以后提示错误 无法将类型“string”隐式转换为“System.Text.StringBuilder”
      

  3.   

    [DllImport("GRAMMAR_ANALYSIS.dll", EntryPoint = "dll_output", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
    public static extern StringBuilder dll_output();
      

  4.   

    我改成这个以后 提示string和StringBuilder不匹配 麻烦告诉我C++的返回值是什么类型 char*我是试了  不行
      

  5.   

    StringBuilder 它是内存域,char* 和 string 不是一个东西好不,你去看下 C++ 和C# 类型对照表 就能解决你的问题了
      

  6.   

    Wtypes.h中的非托管类型  非托管 C语言类型        托管类名                说明
    HANDLE           void*                     System.IntPtr                 32 位
    BYTE             unsigned char             System.Byte                   8 位
    SHORT            short                     System.Int16                  16 位
    WORD              unsigned short           System.UInt16                 16 位
    INT               int                      System.Int32                  32 位
    UINT               unsigned int            System.UInt32                  32 位
    LONG              long                     System.Int32                  32 位
    BOOL              long                     System.Int32                  32 位
    DWORD             unsigned long            System.UInt32                 32 位
    ULONG              unsigned long           System.UInt32                 32 位
    CHAR              char                     System.Char                   用 ANSI 修饰。
    LPSTR             char*              System.String 或 System.StringBuilder   用 ANSI 修饰。
    LPCSTR            Const char*        System.String 或System.StringBuilder   用 ANSI 修饰。
    LPWSTR            wchar_t*           System.String 或System.StringBuilder   用 Unicode 修饰。
    LPCWSTR           Const wchar_t*     System.String 或System.StringBuilder   用 Unicode 修饰。
    FLOAT              Float             System.Single                       32 位
    DOUBLE             Double            System.Double                       64 位
      

  7.   

    我改成StringBuilder 之后返回来的变成乱码了  还有8楼的大神 麻烦具体说说我该怎么改  我是新手 。~
      

  8.   

    还有  若改成用参数取值而不是用返回值返回  就提示
    对 PInvoke 函数“GRA!GRA.Form1::dll_output”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
      

  9.   

    参数类型问题,你用的char*对应c#里面的类型了吗?
     //c++:char *            ----    c#:string       //传入参数
            //c++:char *            ----    c#:StringBuilder//传出参数
            //c++:char *变量名      ----    c#:ref string 变量名
            //c++:char *输入变量名  ----    c#:string 输入变量名
            //c++:char *输出变量名  ----    c#:[MarshalAs(UnmanagedType.LPStr)] 
      

  10.   

    应该使用byte[]来接收。[DllImport("GRAMMAR_ANALYSIS.dll", EntryPoint = "dll_output" CallingConvention = CallingConvention.StdCall)]
            public static extern byte[]dll_output();