有没有精通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#这部分代码运行不成功,分析可能在三个地方
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));
}
}
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;
}
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一定会引用成功,但是有参的需要确认参数是否正确。