被调dll函数
ykt_readopencardno_local(char * pRegion, char * pDeptid, char *  pDeptKey, char * pCardtype, char * pCardno, char *  pWarnmsg, char * pErrmsg);C#调用代码:
        [DllImport("kernel32.dll")]
        private extern static IntPtr LoadLibrary(String path);
        [DllImport("kernel32.dll")]
        private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);
        [DllImport("kernel32.dll")]
        private extern static bool FreeLibrary(IntPtr lib);        public static IntPtr hLib;        public Integrated(String DLLPath)
        {            hLib = LoadLibrary(DLLPath);
        }        //将要执行的函数转换为委托 
        public Delegate Invoke(String APIName, Type t)
        {
            IntPtr api = GetProcAddress(hLib, APIName);
            return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
        }
        public delegate int ykt_readopencardno_local(byte[] pRegion, byte[] pDeptid, byte[] pDeptKey, ref char pCardtype, ref StringBuilder pCardno, ref long pWarnmsg, ref long pErrmsg);//编译 问题:输出参数pCardno用StringBuilder类型报错:试图读取或写入受保护内存,这通常是指示其他内存已损坏!
求高手指点。

解决方案 »

  1.   

    pCardno Char(20) 卡号 可包含数字和字母
      

  2.   

     ykt_readopencardno_local(char * pRegion, char * pDeptid, char * pDeptKey, char * pCardtype, char * pCardno, char * pWarnmsg, char * pErrmsg);
    -----------------------------------------------c++         c#
    char * ====>string 
      

  3.   

    string也试过,跟用StringBuilder报的错一样,我也试过用char[]和byte[] 但是错误的提示用try都抓不到  ,窗口一闪而过, 不知道为什么
      

  4.   

    [MarshalAs(UnmanagedType.LPStr)] string 试试
      

  5.   

    [MarshalAs(UnmanagedType.LPStr)] string 这个怎么用,能否给具体代码看看。
    我这样报错        public delegate int ykt_readopencardno_local(byte[] pRegion, byte[] pDeptid, byte[] pDeptKey, ref char pCardtype, ref [MarshalAs(UnmanagedType.LPStr)]string pCardno, ref long pWarnmsg, ref long pErrmsg);
      

  6.   

    lz,把平台调用弄复杂了,一般的时候采用静态调用就可以,不要动态调用,
    就一个API函数而已,直接这样使用:DllImport("sqlite3.dll", EntryPoint = "ykt_readopencardno_local", CallingConvention = CallingConvention.Cdecl)] 
    public static extern int ykt_readopencardno_local(string pRegion, string pDeptid, string  pDeptKey, string pCardtype, string  pCardno, string pWarnmsg,string pErrmsg);
      

  7.   

    我最开始也是用的静态调用,但报错:说DLL加载失败,没有发现该模块。后来就用动态调用了。
      

  8.   

    跟dll环境应该没关系,我用long和byte来接收卡号参数pCardno是能接收到值的,只是值不对,正确的卡号是字母和数字组合,long和byte接收到的是不知道什么意义的纯数字串,所以应该不是dll的问题。
      

  9.   

    “说DLL加载失败,没有发现该模块”这类问题很好解决,无非两种情况:
    1、路径不正确,你可以先用绝对路径使用!
    2、缺少依赖的dll,用VC6的DEPENDS.EXE工具查看,
       把所有依赖的(非系统)的dll,拷贝到相同的目录下!
      

  10.   

    楼上的经验之谈啊。我补点,可能需要给定容器大小,例如byte[] bytes=new byte[1024];
      

  11.   

    呵呵,谢谢各位,我解决了。C++ char * 输出变量名  对应 C# [MarshalAs(UnmanagedType.LPStr)]StringBuilder  。用[MarshalAs(UnmanagedType.LPStr)]StringBuilder接收卡号就行了。还是谢谢各位,让我学到了其他东西。
      

  12.   

    不过,还有个问题,VC++ char *类型输出参数储存16进制,不知道C#里要用哪种对应的类型。string ,ref string,StringBuilder,[MarshalAs(UnmanagedType.LPStr)]StringBuilder,ref byte,byte[] 都用了,还是不行。求教!!!
      

  13.   

    没关系,你先用StringBuilder获取,在进行一下转换就可以了:      public static byte[] GetBytes(string hexString, out int discarded)
            {
                discarded = 0;
                string newString = "";
                char c;
                // remove all none A-F, 0-9, characters
                for (int i=0; i<hexString.Length; i++)
                {
                    c = hexString[i];
                    if (IsHexDigit(c))
                        newString += c;
                    else
                        discarded++;
                }
                // if odd number of characters, discard last character
                if (newString.Length % 2 != 0)
                {
                    discarded++;
                    newString = newString.Substring(0, newString.Length-1);
                }            int byteLength = newString.Length / 2;
                byte[] bytes = new byte[byteLength];
                string hex;
                int j = 0;
                for (int i=0; i<bytes.Length; i++)
                {
                    hex = new String(new Char[] {newString[j], newString[j+1]});
                    bytes[i] = HexToByte(hex);
                    j = j+2;
                }
                return bytes;
            }