小弟我做的是一个 C# 对 c++ dll的调用。
c# 中函数声明 及 调用如下:
       public static extern int Convert(string x,string y);//声明
   
       string a=.....;
       string b=.....;
       Convert(a,b);//调用
当我修改代码的非字符串部分后,首次编译运行时,在第四行的调用部分出现异常:"attempted to read or write protected memory...........",然后再次运行就没事了。不知哪位高人知道这是什么问题啊?

解决方案 »

  1.   

    public   static   extern   int   Convert(StringBuilder   x,StringBuilder   y);
      

  2.   

    string变量创建后就不能再修改。C++ dll可能直接修改了x、y。
      

  3.   

    are you sure your c++ code is correct? and using MarshalAs..attribute to marshal your x, y parameters like [MarshalAs(UnmanagedType.LPStr)]
      

  4.   

    show your c++ code function signature
      

  5.   

    没遇到过,可能是调用dll里面的函数出异常了.读和写保护?看下调用的dll属性
      

  6.   

    问题补充:这种情况在调试中出现的,如果是运行exe,问题就一直存在了。1楼的,谢谢,我试了,不行地。
      

  7.   

    dll没有问题,首次编译后,在debug时,可以正常调用,但是首次编译和exe直接运行都不行。
      

  8.   

            public static extern int Convert([MarshalAs(UnmanagedType.LPStr)] string x, [MarshalAs(UnmanagedType.LPStr)] string y);
    3楼:这个意思?不行啊。。
      

  9.   

    can you show   your   c++    function   signature?
      

  10.   


    Certainly! like this!
    extern "C" __declspec(dllexport) int __cdecl Convert(char*,char*);// signature
    anything wrong?
      

  11.   

    “dll没有问题,首次编译后,在debug时,可以正常调用,但是首次编译和exe直接运行都不行。”
    -----------------------------------------------------------------------------check:运行时使用的是release模式?Convert内部的代码也贴出来,more code...
      

  12.   

    extern "C" __declspec(dllexport) int __cdecl Convert(char*,char*);//声明
    int Convert(char* x,char* y) //实现
    { int i=0;
    InitAgent(SM_ALL_TYPE,10000);
    i = ConvertDoc(x,y); //
    CleanAgent();

    return 0;
    } 这是Convert()的实现,红色部分是人家的api,没有代码。
    楼上我说运行就是双击exe,运行还分debug,release?
      

  13.   

     [DllImport("*****.dll", CharSet=CharSet.*****, CallingConvention=CallingConvention.Cdecl)]
    public   static   extern   int   Convert(string   x,string   y);//pay attention to charset, call convention ..
      

  14.   

    楼上说的对,前边charset出现过问题。刚我把c++ dll 中的 Convert()实现体删了,返回一个0,结果就没事了。那问题应该在Convert()的实现中,应该是 i=ConvertDoc(x,y);这句。难道他的这个dll (我在C++中调用的别人的) 在首次加载时不能访问托管代码?
      

  15.   

    I also doubt that the problem in your c++ code..
      

  16.   

    对啊,我就说是呢。
    我的dll 把 字符串变量直接给了 他的dll,我现在正在试把传过来的字符串
    重新定义一下,然后再传过去呢。
      

  17.   

    楼上大哥,别涮我们了,我正着呢。问题新进展:
    和人家的dll没关系,我把字符串从c#传到我自己的dll,使用strcpy()做一个简单的复制,都过不来,问题依旧,而且调试几次都不行。现在的问题:怎么把字符串传进去,并且使dll可以访问的到?饿死我了,两顿没吃了,这个问题......
      

  18.   

    to complete resolve this problem , just write a strcpy() using c by yourself(very simple)..then invoke it in your C# code..pay attention to calling conversion,,
      

  19.   


            [DllImport("**.dll", CharSet = CharSet.Auto)]
            public static extern int Convert(ref byte[] x, ref byte[] y);使用的时候先将字符串转化成byte[]
    string a;
    ...
    byte[] x = Encoding.ASCII.GetBytes(a);
    ...
    Convert(x,y);
      

  20.   

    show your intact code....include c++ implementation
      

  21.   

    using byte array is a good idea..
      

  22.   

    To: hapen_zhang
    用string 传,用byte[]传,用char[]传,我都试了,并且网上有各种例子,用什么的都有,都可以、但我的问题还没解决。我把字符传传进去,然后把参数不做任何变化 return ,c#可以看到返回的串。但是就是不能在dll 接受并访问。
      

  23.   

    但是就是不能在dll   接受并访问。what's your means? 
      

  24.   

    我的意思是
    如果把Convert()返回类型改成 char*在c#中接受返回值,能并能显示,说明指针过去了。但是过去的指针 在dll 中访问时出
    Message = "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
    这个异常,我认为这是不能访问c#的托管数据?
    不知道我理解的对不对,我搜到其他帖子也是关于dll调用的,但是没有一个出这个异常。
      

  25.   

    dll中定义的串可以正确的传回来,怒!!!!!!To: 南河三。
    能给写的简单的例子不,用strcpy().我是这样写的:
    char* Convert(char* x,char* y)
    {
       char* test="";   strcpy(test,x);   return test;
    }这样和直接使用 参数x 做ConverDoc(x)调用出的异常一样,并且不在是调试一次后可用了,
    是怎么样都不可用了。
      

  26.   

    dll中定义的串可以正确的传回来,怒!!!!!!To: 南河三。
    能给写的简单的例子不,用strcpy().我是这样写的:
    char* Convert(char* x,char* y)
    {
       char* test="";   strcpy(test,x);   return test;
    }这样和直接使用 参数x 做ConverDoc(x)调用出的异常一样,并且不在是调试一次后可用了,
    是怎么样都不可用了。
      

  27.   

    你要补一下基本功。 char*   test=""; strcpy(test,x); return   test; 
    函数结束后,这个地址就无效了。栈释放。
      

  28.   


    char *strcpy(char *strDest, const char *strSrc);
    {char *address =strDest;
    while( (*strDest++ = * strSrc++) != ‘\0’ );return address;
    }
      

  29.   

    一语中的!我底层的东西不行。
    “函数结束后“ 指的是Convert()?
    没太听懂,能不能麻烦你说的细一点?或者给个例子,我原来的代码开始就发到上面了
    在第13楼,那代码有有同样的问题吗?
      

  30.   

    QQ:329270491
    MSN:[email protected]
    能加你吗?南河三?我两个都在。
      

  31.   

    例子我已经给出了,函数执行完后,函数中所有局量变量就都失效了。所以在C++返回int,class都是可以的,因为还要有一个复制的过程,,但返回局部地址的指针不可以,。。C++之忌。
      

  32.   

    问题解决:
    很怪异,我调用的dll(别人的),他的头文件中有个宏是 DWORD 值 0x0001L,
    当我建的是个exe工程时,传递这个值给一个函数,执行正确。
    但当我建的是个dll,时,仍然传递这个值就出这个错误,然后我这个DWORD 值使用int 转换一下。
    再调用正常!
    谁能想的到啊!