在c#中通过DllImport调用vc6编写的dll,结果出现“尝试读取或写入受保护的内存,这通常指示其他内存已损坏”的错误,抛出AccessViolationException异常。
    c中函数原型为fx(LPTSTR a,card b,bool c,int d,int e,char *f short g)我在c#中写成
                 fx (string a,card b,bool c,int d,int e,string f,int g)
其中card在c中为结构类型,在c#中已改为类,c#中程序运行结果正确,就是出现以上异常,望高手解救!

解决方案 »

  1.   

    [DllImport()]调用代码怎么写的啊??
      

  2.   

    [DllImport("DLL文件名")]
    函数声明
      

  3.   

    c#代码如下:[StructLayout(LayoutKind.Sequential)]
            public class card
            {
                public char[] name;
                public char[] sex;
                public char[] birthday;
                public char[] address;
             }        [DllImport("infodll.dll")]
            public static extern int fx(string imagefile_name,card idcard,bool Result,int net,int Content,string  HeadImg,int Type);private void button1_Click(object sender, EventArgs e)
            {
                String imgfile = "img.jpg";
                String imghead = "head.jpg";
                card idcard = new card();
                RecogIdcardExALL(imgfile,idcard,true,0,17,imghead,1);            
                 
            }调用的函数fx原型为fx(LPTSTR a,card b,bool c,int d,int e,char *f short g)
      

  4.   

    调用的函数fx原型为fx(LPTSTR a,card b,bool c,int d,int e,char *f,short g),不好意思,忘写了个逗号
      

  5.   

    [StructLayout(LayoutKind.Sequential)]
    public struct card
    {
    [MarshalAs( UnmanagedType.LPTStr )]
    public StringBuilder name;
    [MarshalAs( UnmanagedType.LPTStr )]
    public StringBuilder sex;
    [MarshalAs( UnmanagedType.LPTStr )]
    public StringBuilder birthday;
    [MarshalAs( UnmanagedType.LPTStr )]
    public StringBuilder address;
    }[DllImport("infodll.dll")]
    public static extern int fx(string imagefile_name,
    [Out]ref card idcard,bool Result,int net,int Content,string HeadImg,int Type);//Call
    String imgfile = "img.jpg";
    String imghead = "head.jpg";
    card idcard = new card();
    idcard.name = new StringBuilder( 256 );//Init buffer size with 256
    idcard.sex = new StringBuilder( 256 );//Init buffer size with 256
    idcard.birthday = new StringBuilder( 256 );//Init buffer size with 256
    idcard.address = new StringBuilder( 256 );//Init buffer size with 256RecogIdcardExALL(imgfile,idcard,true,0,17,imghead,1);
      

  6.   

    Knight94(愚翁)兄:试了你的方法不行啊,晕了。
      

  7.   

    感觉是你的
    public class card
            {
                public char[] name;
                public char[] sex;
                public char[] birthday;
                public char[] address;
             }
    把c的定义贴出来
      

  8.   

    to 试了你的方法不行啊,晕了。把dll中的struct和函数的定义贴出来,然后大致说说哪些是传进参数,哪些是传出的。
      

  9.   

    dll中的struct是这样定义的:typedef struct{char name[40];char sex[10];char birthday[50];char address[200];}dll中的函数是这样定义的fx(LPTSTR a,card &b,bool c,int d,int e,char *f ,short g)其中a和f都是图像文件,如:a="c:\\photo.jpg";现在我在c#中使用就会出现“尝试读取或写入受保护的内存”的错误。
      

  10.   

    [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi //这里看具体的c++要求)]
    public class card
    {
    [MarshalAs(UnmanagedType.LPArray, 
      ArraySubType=UnmanagedType.ByValTStr, SizeConst=40)]
    public string name;
    [MarshalAs(UnmanagedType.LPArray, 
     ArraySubType=UnmanagedType.ByValTStr, SizeConst=10)]
    public string sex;
    [MarshalAs(UnmanagedType.LPArray, 
     ArraySubType=UnmanagedType.ByValTStr, SizeConst=50)]
    public string birthday;
    [MarshalAs(UnmanagedType.LPArray, 
     ArraySubType=UnmanagedType.ByValTStr, SizeConst=200)]
    public string address;
    }
            [DllImport("infodll.dll")]
            public static extern int fx(string imagefile_name,ref //这里加ref 
    card idcard,bool Result,int net,int Content,string  HeadImg,int Type);
      

  11.   

    hdt(倦怠) 兄,你的方法出错了:“无法封送处理类型为‘card’的‘name’:无效的托管/非托管类型组合(数组字段必须与byvalarray或safearray成对出现)。”晕
      

  12.   

    是不是char *f这里的问题,字符真正在c#中用string行吗
      

  13.   

    sorry ,copy past error
    ....public class card
    {
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst=40)]
    public string name;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=10)]
    public string sex;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=50)]
    public string birthday;
    [MarshalAs(UnmanagedType.ByValTStr,, SizeConst=200)]
    public string address;
    }
      

  14.   

    have a try!
    [StructLayout(LayoutKind.Sequential)]
    public class card
    {
    [MarshalAs(UnmanagedType.LPArray, SizeConst=40)]
    public byte[] name;
    [MarshalAs(UnmanagedType.LPArray, SizeConst=10)]
    public byte[] sex;
    [MarshalAs(UnmanagedType.LPArray, SizeConst=50)]
    public byte[] birthday;
    [MarshalAs(UnmanagedType.LPArray, SizeConst=200)]
    public byte[] address;
    } [DllImport("infodll.dll")]
    public static extern int fx(string imagefile_name,ref card idcard,
    bool Result,int net,int Content,string HeadImg,int Type);//Init card as follows
    card idcard = new card();
    idcard.name = new byte[40];
    idcard.sex = new byte[10];
    idcard.birthday = new byte[50];
    idcard.address = new byte[200];
      

  15.   

    用UnmanagedType.LPArray会出现:“无法封送处理类型为‘card’的‘name’:无效的托管/非托管类型组合(数组字段必须与byvalarray或safearray成对出现)。”错误
      

  16.   

    按hdt(倦怠) 的方法处理了,开始时错误依旧,然后把第一个参数加上[MarshalAs(UnmanagedType.LPTSTR)]就没有错误了,不过函数执行结果不对,紧接着我把加上的这句去掉再运行,结果出来了并且正确,但却出现如下错误:“检测到 FatalExecutionEngineError
    Message: 运行库遇到了错误。此错误的地址为 0x79ef067e,在线程 0xd58 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。
    ”郁闷死!!
      

  17.   

    .net 的字符串是unicode的,而C++的可能是ansi,这里需要设置为一样
    [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi //这里看具体的c++要求)]
    public class card
    {
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst=40)] //如果设置不对,结果肯定不对,且会破坏堆栈,
         public string name;}
      

  18.   

    hdt(倦怠) 兄:开始设的是auto,现在设的是ansi,错误依旧晕,要疯了
      

  19.   

    类card返回的结果都是对的,感觉好像是第一个参数string imagefile_name有点儿问题
      

  20.   

    [DllImport("infodll.dll")] //这个申明也加CharSet=Ansi 试试
      

  21.   

    dllimport中设成charset.auto程序无错但返回结果不对,设成charset.ansi程序返回结果正确,但错误依旧
      

  22.   

    DllImport中设成charset.auto程序不出错但返回结果不对,设成charset.ansi运行结果正确但出错
      

  23.   

    不是string就是card错了。这种错误就一个原因,格式不对。错了,必定会挂掉。要是对了,以后就对了。可以把各种类型分开试试看。
    c的struct最好用c#的struct来port.这样容易一些。因为c#的struct可以显示内存布局。只要你布局得和c的内存布局一模一样就肯定能过。
      

  24.   

    mooniscrazy(月色疯狂) :你说的我知道,但各种方法都试了,没办法,通不过啊
      

  25.   

    娃哈哈哈。搞定了!!!
      非常感谢hdt(倦怠)、Knight94(愚翁)、mooniscrazy(月色疯狂),有了你们的大力帮助才得以搞定,希望以后多多指教!