2023年12月3日发(作者:)

c#调用Delphi的dll函数遇到的问题及解决方法c# 调用Delphi的dll时,

1.如果dll中的函数参数含有var,则c#中要加上ref(引用);

否则,会有提示错误:“尝试读取或写入受保护的内容。这通常指示其他内存已损坏”。

2.如果dll中的参数是THandle类型,在c#中用IntPtr代替。

3.如果dll中的参数是PChar类型,在c#中应该用byte[]代替。

使用网上说的用ref string或StringBuilder代替PChar都有问题。另外,这里有一些类型对照:dephi c++ C#

PChar 32位字符型指针 unsigned char * String /byte[]

THandle 句柄 *int IntPtr下面是具体例子:

假设有一个Delphi写的dll名字为“”;

它的函数有:

(1)OpenCommPort: 打开串行通讯端口

语法:

function OpenCommPort(Port: Integer; BaudRate: Integer): Thandle;

参数说明: Port:端口号,允许值1-256。 BaudRate:端口波特率,允许值:通常是9600。。

如果函数调用成功,返回的值就是端口句柄,用于其它函数调用。当返回的值是-1时,端口无效或正在使用;当返回的值是0时,无法打开端口。

(2) CallClock: 显式联机命令

语法:

function CallClock(hPort: THandle; Clock_id: Integer): Boolean;

参数说明:

hPort: 端口句柄,通过调用OpenCommPort函数得到

clock_id: 机号,允许值: 0-255。

返回变量: 如果返回为True表示联机成功,如果返回为False表示联机失败。

(3)ReadICCard: 读IC卡信息

语法:

function ReadICCard(hPort: THandle; CardNo, CardName: PChar; var Money, Times, Ver: Integer): Boolean;

参数说明:

hPort: 端口句柄, 调用OpenCommPort函数得到,需要联机

CardNo: 返回卡号,16位,

CardName: 返回姓名,长度不小于16位

Money: 返回卡上金额 Times: 返回充值次数

Ver: IC卡格式, 允许值如下: 0830

返回变量: 如果返回False表示失败,如果返回True表示成功=========================================================================================================================================================================================那么,在c#中可以使用以下方法动态加载dll:class ReadWriteCard

{

public struct info

{

public byte[] CardNo;

public byte[] CardName;

public int Money ;

public int Times ;

public int Ver ;

}

public class readwriteDll

{

[DllImport("", EntryPoint = "OpenCommPort", SetLastError = true, CharSet = e,

ExactSpelling = true, CallingConvention = l)]

public static extern IntPtr OpenCommPort(int port,int RaudRate); [DllImport("", EntryPoint = "CallClock", SetLastError = true, CharSet = e,

ExactSpelling = true, CallingConvention = l)]

public static extern bool CallClock(IntPtr hport, int Clock_id); [DllImport("", EntryPoint = "ReadICCard", SetLastError = true, CharSet = e,

ExactSpelling = true, CallingConvention = l)]

public static extern bool ReadICCard(IntPtr hport, byte[] CardNo, byte[] CardName, ref int Money, ref int Times,refint ver);

}然后,在另一个方法调用这里的函数: private void button1_Click(object sender, EventArgs e)

{

IntPtr portptr = mmPort((),());

int port = (ng());

bool isclock;

("端口句柄:" + portptr);//+ng());

if (port != -1 && port != 0)

{

//联机

isclock = ock(portptr, ());

if (isclock)

{

("联机成功!");

//读卡

temp = new ();

= new byte[255];

me = new byte[255];

= 0;

= 0;

= 0000;

("正在读卡...!");

try

{

bool suc = Card(portptr, , me, ref ,ref , ref );

(ng());

if (suc)

{

("读卡成功!");

}

else

{

("读卡失败!");

}

}

catch (Exception ex)

{

(e, "警告:出错了...");

}

("正在关闭端口...!");

if (ommPort(()))

{

("已经关闭端口!");

}

}

else

{

("联机失败!");

ommPort(());

} }

else if (port == 0)

{

("无法打开端口!");

}

else if (port == -1)

{

("端口无效或正在使用!");

}

}