[DllImport("SmartKeyIO.dll", EntryPoint = "GetSystemInfo", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]    public static extern int[] GetSystemInfo(int DeviceID, int DeviceType);如下调用    
 int[] systemInfo = IC.GetSystemInfo( 86,1);//获取考勤机状态信息
        if (systemInfo[0] == -1)
        {
            Response.Write("<script>alert('当前设备错误');</script>");
            IC.MemRelease();
            return;
        }出现了错误:无法封送处理“return value”: 无效的托管/非托管类型组合。
请高手帮忙,初学者做毕业设计呵呵!

解决方案 »

  1.   

    [DllImport("SmartKeyIO.dll", EntryPoint = "GetSystemInfo", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
      public static extern IntPtr GetSystemInfo(int DeviceID, int DeviceType);int len=4; //这里len的长度替换为GetSystemInfo函数返回的int数组的实际长度
    int[] systemInfo =new int[len];
    IntPtr ptr= IC.GetSystemInfo( 86,1);//
    Marshal.Copy(ptr,systemInfo,0,len*4);  //因为int占用4byte,所以长度乘4
      

  2.   

    您好,Marshal.Copy(ptr,systemInfo,0,len*4);这是什么作用?
    要返回数组类型的都要用到IntPtr吗?谢谢!
      

  3.   


    还是有不对!无法将类型 int[] 隐式转换为 System.IntPtr
      

  4.   


    把你的代码贴出来,我给的代码不会出现这种情况   int[] 隐式转换为 System.IntPtrMarshal.Copy(ptr,systemInfo,0,len*4);
    是将GetSystemInfo返回的指针开始的内容拷到systemInfo数组中去,长度是len*4的byte单位
      

  5.   


    protected void Button1_Click(object sender, EventArgs e)
        {
            bool Comm =IC.OpenComm(1,9600);//初始化串口
            if(!Comm)
            Response.Write("<script>alert('串口初始化失败');</script>");
             int len=4; //这里len的长度替换为GetSystemInfo函数返回的int数组的实际长度
        int[] systemInfo =new int[len];
        systemInfo = IC.GetSystemInfo(deviceID, deviceType);
            if (systemInfo[0] == -1)
            {
               
                IC.MemRelease();
                return;
            }
        }就写了这么几句.
      

  6.   


    protected void Button1_Click(object sender, EventArgs e)
        {
            bool Comm =IC.OpenComm(1,9600);//初始化串口
            if(!Comm)
            Response.Write("<script>alert('串口初始化失败');</script>");
             int len=4; //这里len的长度替换为GetSystemInfo函数返回的int数组的实际长度
        int[] systemInfo =new int[len];
        systemInfo = IC.GetSystemInfo(deviceID, deviceType);
            if (systemInfo[0] == -1)
            {
               
                IC.MemRelease();
                return;
            }
        }就写了这么几句.
      

  7.   

    先把DLL声明的返回类型改为IntPtr,按前面的代码进行测试,有问题再说上面的代码和最初的代码就没有变化,肯定还是有问题的
      

  8.   


    DLL声明的返回类型改为IntPtr后出现了: 无法在 DLL“SmartKeyIO.dll”中找到名为“GetSystemInfo”的入口点
      

  9.   

    出现这个问题说明EntryPoint = "GetSystemInfo", 这个地方有问题,你用工具查看下它的导出函数的名称是什么?另外之前出现的问题是无法封送处理“return value”: 无效的托管/非托管类型组合。,这说明EntryPoint 这里写得是对的,你再检查下EntryPoint 
      

  10.   

    不好意思,是下面的代码:
     protected void Button1_Click(object sender, EventArgs e)
        {
            bool Comm =IC.OpenComm(1,9600);//初始化串口
            if(!Comm)
            Response.Write("<script>alert('串口初始化失败');</script>");
             int len=4; //这里len的长度替换为GetSystemInfo函数返回的int数组的实际长度
        int[] systemInfo =new int[len];
        IntPtr ptr = IC.GetSystemInfo(deviceID,deviceType);
       
        Marshal.Copy(ptr, systemInfo, 0, len * 4);
            if (systemInfo[0] == -1)
            {
               
                IC.MemRelease();
                return;
            }
         }
      

  11.   


    确认EntryPoint 正确后现在是什么情况
      

  12.   

    EntryPoint是对的; 问题还是这样
      

  13.   

    请问一下在动态链接库说明里面是这么说的:
    14、查询系统信息
    GetSystemInfor(DeviceID,DeviceType,CardCapacity,RecordCapacity,CardNumber, RecordNumber)                                     
    执行成功返回True,执行失败返回 False
    参数名称 参数类型 数据类型 参数说明
    DeviceID 设定值 整数 考勤机的ID号:(1-255)
    DeviceType 设定值 整数 考勤机类型(考勤机:DeviceType=1)
    CardCapacity 返回值 整数 所能容纳卡片的数量
    RecordCapacity 返回值 整数 所能容纳记录的数量
    CardNumber 返回值 整数 当前卡片的数量
    RecordNumber 返回值 整数 当前记录的数量
    例如:查询考勤机ID为2的系统信息
          GetSystemInfor (2,1,CardCapacity,RecordCapacity,CardNumber,RecordNumber)到底要怎么调用这个GetSystemInfor 我把函数封装在IC类中;这个函数到底怎么调用啊;请高手指点!
      

  14.   

    [DllImport("SmartKeyIO.dll", EntryPoint = "GetSystemInfo", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
      public static extern bool GetSystemInfo(int DeviceID, int DeviceType,ref int CardCapacity,ref int RecordCapacity ,ref int CardNumber,ref int RecordNumber );参数中的返回值就用ref,这样调用成功后就有返回值了
      

  15.   

    嗯,谢谢!这样之前的错误不挑出来了。但是又有新的问题产生了:
    用户代码未处理 System.AccessViolationException
      Message="尝试读取或写入受保护的内存。这通常指示其他内存已损坏。"
      Source="App_Code.k_wex0mm"
      StackTrace:
           在 IC.GetSystemInfor(Int32 DeviceID, Int32 DeviceType, Int32& CardCapacity, Int32& RecordCapacity, Int32& CardNumber, Int32& RecordNumber)
           在 teacher_日考勤统计.Button1_Click(Object sender, EventArgs e) 位置 c:\Users\M\Desktop\登陆界面\teacher\日考勤统计.aspx.cs:行号 43
           在 System.Web.UI.WebControls.Button.OnClick(EventArgs e)
           在 System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
           在 System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
           在 System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
           在 System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
           在 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
      InnerException: 
      

  16.   

    你看有没有DEMO调用这个函数的代码贴出来看看,最好DLL函数声明的原型(.h文件))也贴出来
      

  17.   


      int deviceID=3; //自己设置的一个考勤机号,并赋值
            int deviceType = 1;
            int CardCapacity = 8, RecordCapacity = 8, CardNumber = 8, RecordNumber = 8;
            bool Comm = IC.OpenComm(1, 9600);//初始化串口
            if (!Comm)
                Response.Write("<script>alert('串口初始化失败');</script>");        bool systemInfo = IC.GetSystemInfor(deviceID, deviceType, ref  CardCapacity, ref  RecordCapacity, ref  CardNumber, ref  RecordNumber);
    我就写了上面这么一点点的代码就遇到问题了;
    DEMO中查找了关于GetSystemInfor的代码如下:begin
       ID:=1; DeviceType:=1;
       if GetSystemInfor(ID,
                         DeviceType,
                         CardCapacity,
                         RecordCapacity,
                         CardNumber,
                         RecordNumber) then
       EditDisplay.text:='CardCapacity:'+IntToStr(CardCapacity)+#10#13+
                      'RcordCapacity:'+IntToStr(RecordCapacity)+#10#13+
                      'Card Numb.:'+IntToStr(CardNumber)+#10#13+
                      'Record Numb.:'+IntToStr(RecordNumber)
       else
       EditDisplay.text:='GetSystemInfor Error';
    end;
      

  18.   

    贴DEMO中GetSystemInfor的声明,以及调用时每个参数定义的类型ID,DeviceType...目的是检查声明的类型和给的说明是否一致GetSystemInfor(DeviceID,DeviceType,CardCapacity,RecordCapacity,CardNumber, RecordNumber)   
    执行成功返回True,执行失败返回 False
    参数名称 参数类型 数据类型 参数说明
    DeviceID 设定值 整数 考勤机的ID号:(1-255)
    DeviceType 设定值 整数 考勤机类型(考勤机:DeviceType=1)
    CardCapacity 返回值 整数 所能容纳卡片的数量
    RecordCapacity 返回值 整数 所能容纳记录的数量
    CardNumber 返回值 整数 当前卡片的数量
    RecordNumber 返回值 整数 当前记录的数量
      

  19.   

    http://topic.csdn.net/u/20101231/10/3efd8bfb-b875-4951-8808-ce2f842e9bbb.html?seed=1578991458&r=70973210#r_70973210