C# 调用DLL问题,由Delphi代码改为C#

有没有精通C#和DELPHI的朋友
最近公司拿到个DELPHI写的调用DLL实现IC卡读写源码,要转成C#的
有个方法不知道怎么写了

以下是DELPHI调用DLL
以下是实现

function JT_CPUCommand(nHandle:integer;sCommand:pchar;nLenCom:integer;sReply:pchar;pLenRep:pinteger):integer;stdcall;external dll_name;
procedure TForm1.btnProClick(Sender: TObject);
var
sarr,sarr2: array[0..100] of char;
sCommand, sReply,sSw :array[0..100] of char;
iretLen:integer;
begin
fillchar(sArr,sizeof(sArr),0);
fillchar(sArr2,sizeof(sArr2),0);

strpcopy(sCommand, edtprocommand.text);
fillchar(sReply,sizeof(sreply),1);
fillchar(sSw,sizeof(sSw),1);
ret := JT_CPUCommand(fd,sCommand,length( edtprocommand.text),sReply,@iRetLen);
Memo1.Lines.add('pro command ret:' + inttostr(ret ) + ',retlen:' + inttostr( iretLen) + ' resp:' + strpas(sReply));
end;

我改成C#的代码
C# 引入DLL

[DllImport("ICC_HD.dll")]
public extern static int JT_CPUCommand(int _fd, byte[] sCommand, int edtprocommandLenth, byte[] sReply, IntPtr iRetLen);

C# 点击事件实现

    private void btnPro_Click(object sender, EventArgs e)
    {
        byte[] sCommand = new byte[100];
        string tmpArr = edtprocommand.Text;  //由于没有DELPHI的strpcopy功能,只能写循环赋值,求更便捷办法
        for (int i = 0; i < 100; i++)
        {
            if (i < tmpArr.Length)
            {
                sCommand[i] = (byte)Convert.ToInt32(tmpArr.Substring(i, 1));
            }
        }
        byte[] sReply = new byte[100]; //由于没有DELPHI的fillchar功能,只能写循环赋值为1,求更便捷办法
        for (int i = 0; i < 100; i++)
        {
            sReply[i] = (byte)1;
        }
        int iRetLen = 0;
        IntPtr intPtr = GetAddress(iRetLen);
        int ret = JT_CPUCommand(clsIC.fd, sCommand, edtprocommand.Text.Length, sReply, intPtr);
        riTxt.AppendText("\r\npro command ret:" + ret.ToString() + ",retlen:" + iRetLen.ToString() + " resp:" + Encoding.Default.GetString(sReply));
    }
  public static IntPtr GetAddress(int value)
    {
        GCHandle gcHandle = GCHandle.Alloc(value, GCHandleType.Pinned);//访问对象
        IntPtr intPtr = gcHandle.AddrOfPinnedObject();//获取对象地址
        return intPtr;
    }

但是DELPHI上面调用是成功的,为什么C#这部分代码运行不成功,分析可能在三个地方

  1. Delphi中 strpcopy(sCommand, edtprocommand.text);
    C#中我用的是

         string tmpArr = edtprocommand.Text;  //由于没有DELPHI的strpcopy功能,只能写循环赋值,求更便捷办法
         for (int i = 0; i < 100; i++)
         {
             if (i < tmpArr.Length)
             {
                 sCommand[i] = (byte)Convert.ToInt32(tmpArr.Substring(i, 1));
             }
         }
    
  2. Delphi中 fillchar(sReply,sizeof(sreply),1);
    C#中我用的是

          byte[] sReply = new byte[100]; //由于没有DELPHI的fillchar功能,只能写循环赋值为1,求更便捷办法
          for (int i = 0; i < 100; i++)
          {
              sReply[i] = (byte)1;
          }
    
  3. Delphi中 ret := JT_CPUCommand(fd,sCommand,length( edtprocommand.text),sReply,@iRetLen);
    C#中我用的是

           int iRetLen = 0;
           IntPtr intPtr = clsIC.GetAddress(iRetLen);
           int ret = JT_CPUCommand(clsIC.fd, sCommand, edtprocommand.Text.Length, sReply, intPtr);
    

看了下你的代码,回答如下:


//1,字符串拷贝
string tmpArr = string.Copy(edtprocommand.Text);

//2,byte数组赋值 
//创建一个长度为100的byte数组,并且其中每个byte的值为0x01
byte[] sReply = Enumerable.Repeat((byte)0x01, 100).ToArray();

//3,信令调用
int iRetLen = 0;
IntPtr intPtr = GetAddress(iRetLen);
//如果该命令调用不成功, 查看一下clsIC.fd这个参数的合适的值应该是多少
int ret = JT_CPUCommand(clsIC.fd, sCommand, tmpArr.Length, sReply, intPtr);

无参的dll Import一定会引用成功,但是有参的需要确认参数是否正确。