说起来这是个老型号的必达门卡接口,但是客户为了省钱,咱也是没办法,在尝试了无数次失败后,只能请求诸位了。
原定义代码如下:const
  DLL_Name = 'btLock56.dll' ;    function Read_Guest_Card(
                         AReaderType,
                         ACardType,
                         APort,
                         ASector,
                         ABlock: Byte;
                         AHotelPwd: Pchar;
                         ClientID: Longword;
                     var ALockNo,
                         AStartSuite,
                         AEndSuite,
                         ACardID,
                         ASubCardID: integer;
                         ATime: Pchar
                         ):integer; stdcall; External DLL_Name;
原调用部份代码:var
  Time:pchar;
  tmpTime:string;
  HotelPwd:array[0..8] of char;
  rt,LockNo,CardID,SubCardID,StartSuite, EndSuite:integer;
  tmpClientID: Longword;
begin
   LockNo:=0;
   CardID:=0;
   SubCardID:=0;
   StartSuite:=0;
   EndSuite:=0;
   GetMem(Time,11);
   // 酒店密码
   StrPCopy(HotelPwd, Edit2.Text);
   tmpClientID := StrToInt64(edtClientID.Text);
   // 读客人卡
   rt:=Read_Guest_Card(FReaderType,FCardType, FPortNo,FSector,FBlock,@HotelPwd,
                       tmpClientID,LockNo,StartSuite,EndSuite,CardID,SubCardID,Time);
   Edit3.text:=inttostr(LockNo);
   Edit4.text:=inttostr(CardID);
   Edit5.text:=inttostr(SubCardID);
   tmpTime:=strpas(Time);
   FreeMem(Time);
   Edit6.Text:=tmpTime;
   Edit7.Text:=inttostr(Startsuite);
   Edit8.Text:=inttostr(EndSuite);
   case rt of
      0:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 读客人卡成功!';
      1:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 串口被占用或没发现!';
      2:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 设置串口绶冲区大小错误!';
      3:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 设置串口事件掩码!';
      4:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 该串口没有打开!';
      5:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 该串口已打开!';
      7:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 客户标识非法!';
      8:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 注册过期!';
      9:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 找不到加密狗!';
      10:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 卡地址错误!';
      11:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 卡密码错误!';
      12:StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 卡类型错误!';
      else StatusBar1.Panels[1].Text := inttostr(rt)+ ' --> 读客人卡失败!';
   end;end;
以下是我转成C#的代码:        [DllImport("btLock56.dll", EntryPoint = "Read_Guest_Card", SetLastError = true, CallingConvention=CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern int Read_Guest_Card(byte AReaderType, byte ACardType, byte APort, byte ASector, byte ABlock,
                                                 string AHotelPwd, uint ClientID,
                                                 ref long ALockNo, ref long AStartSuite, ref long AEndSuite,
                                                 ref long ACardID, ref long ASubCardID, ref StringBuilder ATime);
以下是C#调用代码:            byte AReaderType;
            byte ACardType;
            byte APort;
            byte ASector;
            byte ABlock;
            string AHotelID;
            string AHotelPwd;
            uint ClientID;            //读卡后返回的值
            long ALockNo=0;
            long AStartSuite=0;
            long AEndSuite=0;
            long ACardID=0;
            long ASubCardID=0;
            string ATime = "";
            
            //变量附值
            APort=Convert.ToByte(c_APort.SelectedIndex + 1);
            AReaderType = Convert.ToByte(c_AReaderType.SelectedIndex + 1);
            if (c_ACardType.SelectedIndex == 0)
            {
                ACardType = Convert.ToByte(65);
            }
            else
            {
                ACardType = Convert.ToByte(68);
            }
            ASector = Convert.ToByte(c_ASector.Text);
            ABlock = Convert.ToByte(c_ABlock.Text);
            ClientID = Convert.ToUInt32(c_ClientID.Text);
            AHotelID = c_AHotelID.Text;
            AHotelPwd = c_AHotelPwd.Text;            ALockNo = Convert.ToInt64(c_ALockNo.Text);
            AStartSuite = Convert.ToInt64(c_AStartSuite.Text);
            AEndSuite = Convert.ToInt64(c_AEndSuite.Text);
            ACardID = Convert.ToInt64(c_ACardID.Text);
            ASubCardID = Convert.ToInt64(c_ASubCardID.Text);
            //ATime = c_ATime.Text;            //int n = 0;
            //try
            //{
                ResultCode=Door_BTLock56.Read_Guest_Card(AReaderType, ACardType, APort, ASector,
                                              ABlock, AHotelPwd, ClientID,
                                              ref ALockNo, ref AStartSuite, ref AEndSuite,
                                              ref ACardID, ref ASubCardID, ref ATime);Delphi代码运行的很好,信息都能正常获取。
转换后,看上去一切非常的好,但是每次一读信息,程序就直接崩溃并且无任何提示。我敢肯定一点的是ref之前的参数都没问题,因为另外有一个写卡的方法用到前七个参数写入数据很正常。
请高手务必帮帮忙,小弟感激不尽。

解决方案 »

  1.   

    把stringbuilder直接ref过去真的没问题吗。。
      

  2.   

    错了,定义部是        public static extern int Read_Guest_Card(byte AReaderType, byte ACardType, byte APort, byte ASector, byte ABlock,
                                                     string AHotelPwd, uint ClientID,
                                                     ref long ALockNo, ref long AStartSuite, ref long AEndSuite,
                                                     ref long ACardID, ref long ASubCardID, ref string ATime);
    不好意思
      

  3.   

    对delphi是一点也不懂
    如果Pchar是类似于char[]的话,要用new string(pchar)以后再传
      

  4.   

    上边说反了,是ToCharArray一下声明
     public static extern int Read_Guest_Card(byte AReaderType, byte ACardType, byte APort, byte ASector, byte ABlock,
                                                     string AHotelPwd, uint ClientID,
                                                     ref long ALockNo, ref long AStartSuite, ref long AEndSuite,
                                                     ref long ACardID, ref long ASubCardID, ref char[] ATime)
    var ATimeChar=ATime.ToCharArray(),再传ref ATimeChar
      

  5.   

    小弟愚钝char[] bb= new char[9];
    string aa = new string(bb);
    是这样吗?
      

  6.   

    这里有一点不明白,请解惑,我查了一些资料,delphi的pchar应该对应C#的string才对呀,为什么是char[] 呢?
      

  7.   


    不了解delphi的pchar。.net的string是个结构体,包括一个表长度的int和真实的字符
      

  8.   

    还有一个问题,为什么之前的AHotelPwd: Pchar;  我直接传string又可以呢?
      

  9.   

    AHotelPwd类型改成StringBuilder试试。
      

  10.   

    您说的方法我之前已经试过了,也是直接崩掉,反复测试后,我认为问题应该是锁定在ref几个参数上,今天我准备试下phommy 的方法
      

  11.   


    =======================================================
    .NET快速开发整合框架(RDIFramework.NET),基于.NET的快速开发、整合框架,给用户和开发者最佳的.Net框架部署方案。
    平台博客:[CNBLOGS]http://www.cnblogs.com/huyong 
         [CSDN]http://blog.csdn.net/chinahuyong
    交流QQ:406590790 (请注明:CSDN)
    平台微博:http://t.qq.com/yonghu86
    邮件交流:[email protected]
      

  12.   

    解决了,用了比较无耐的方法,因为读卡返回的ATime时间作用不大,所以最后将ATime的ref直接去掉。看来这方面的知识还是要恶补一下
      

  13.   

    就此结帖吧,感谢 phommy 大侠