delphi如何调用VC写的dll动态库

lt8024 2010-10-22 04:02:48
有个动态库net.dll

VC的头文件关于函数的定义如下
int WINAPI OnLink_Net(int m_port,int outtime,int Net_Num,char *Net_addr[]);
void WINAPI OnStart_Net(int TY,float FS,BYTE SCH,BYTE ECH,BYTE GN,int TR,BYTE Kb,int Bn);
void WINAPI OnStop_Net(int TY);
int WINAPI OnReadH_Net(short int *addata[],long len);
int WINAPI OnReadL_Net(short int *addata[],long len);
void WINAPI OnClose_Net(void);

在delphi中如何调用他们
1.这几个函数delphi中如何定义
2.delphi如何定义参数并且调用

...全文
293 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
lt8024 2010-10-29
  • 打赏
  • 举报
回复
short int *addata转为delphi一般都是Psmallint或者array of smallint,自然是一维

还有我上面那段话不是我说的,是提供动态库的厂家给的函数说明
OnReadL_Net
函数形式: int WINAPI OnReadL_Net(short int *addata[ ],long len)
说 明: 该函数用于对连接的所有设备多点连续(单通道或多通道)数据采集(低速)。
输入参数: leng 单台网络采集设备采样数据的总点数(一点为16位字),注意:需是1024的倍数。
该参数是长整数。
输出参数: *addata[ ]二维数据数组。采集数据分每台设备存放于数据数组中(例如有两台设备,
addata[1][1024]表示第一台设备采集了1024个数据,addata[2][1024]表示第二台设备采集1024了个
数据);每台设备数据存放规则(以采集4个通道为例):对应数
组中第一个数据为第一通道,第二个数据为第二通道,第三个数据为第三通道,第四个数据为第
四通道,第五个数据为第一通道,第六个数据为第二通道,第七个数据为第三通道,第八个数据
为第四通道··· ···直到数据结束。

  • 打赏
  • 举报
回复
同学,int WINAPI OnReadL_Net(short int *addata[ ],long len)这里的addata[]怎么会是个二维数组呢?上面也是,你怎么老是把指针数组说成是二维数组?这是个整数的指针数组,不是二维数组。
lt8024 2010-10-26
  • 打赏
  • 举报
回复
这个数据一直取的不对

OnReadL_Net
函数形式: int WINAPI OnReadL_Net(short int *addata[ ],long len)
说 明: 该函数用于对连接的所有设备多点连续(单通道或多通道)数据采集(低速)。
输入参数: leng 单台网络采集设备采样数据的总点数(一点为16位字),注意:需是1024的倍数。
该参数是长整数。
输出参数: *addata[ ]二维数据数组。采集数据分每台设备存放于数据数组中(例如有两台设备,
addata[1][1024]表示第一台设备采集了1024个数据,addata[2][1024]表示第二台设备采集1024了个
数据);每台设备数据存放规则(以采集4个通道为例):对应数
组中第一个数据为第一通道,第二个数据为第二通道,第三个数据为第三通道,第四个数据为第
四通道,第五个数据为第一通道,第六个数据为第二通道,第七个数据为第三通道,第八个数据
为第四通道··· ···直到数据结束。
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 lt8024 的回复:]
同学,*addata实际就是一维数组啊,*addata[]就是2维
[/Quote]
*addata怎么看出来时一维数组??*addata[]又怎么看出来是二维数组的?前面的short int是摆设?如果没有前面的short int那*addata这个什么也不是。short int *addata[]这是个指针数组没有任何疑问啊,任何一本c教材都会这么说的。
lt8024 2010-10-26
  • 打赏
  • 举报
回复
同学,*addata实际就是一维数组啊,*addata[]就是2维
ffwin 2010-10-25
  • 打赏
  • 举报
回复

function OnLink_Net(m_port: Integer; outtime: Integer; Net_Num: Integer; Net_addr[]: PChar): Integer stdcall;

procedure OnStart_Net(TY: Integer; FS: Single; SCH: BYTE; ECH: BYTE; GN: BYTE; TR: Integer; Kb: BYTE; Bn: Integer) stdcall;

procedure OnStop_Net(TY: Integer) stdcall;

function OnReadH_Net(var addata[]: SmallInt; len: LongInt): Integer stdcall;

function OnReadL_Net(var addata[]: SmallInt; len: LongInt): Integer stdcall;

procedure OnClose_Net stdcall;

小海贼 2010-10-25
  • 打赏
  • 举报
回复
给你个动态调用DLL的例子
//1、在type处申明
TRegFun=Function(strSerial:PCHAR;strProjectName:PCHAR):Integer;cdecl;
TCheckInputFun=Function(proName:PCHAR;text:PCHAR):Integer;cdecl;
//Integer表示该vc函数返回的是int,proName:PCHAR;text:PCHAR是vc函数中的参数,类型为char*;cdecl这个由vc中申明导出函数的方式决定;
//2、调用函数
function Register_Register(strText:string):Boolean;
var
funcheck:TCheckInputFun;
funReg:TRegFun;
Handle:THandle;
iReturnValue:integer;
strProjectName:string;
begin
strProjectName:= Register_ProjectName();
if length(strProjectName)=0 then
begin
Register_ShowMsg('程序配置不正确,请与管理员联系!');
result:=false;
exit;
end;
Handle:=LoadLibrary('DynamicDLL.dll'); //DLL文件需要为当前目录下
if Handle=0 then
begin
Register_ShowMsg('未能找到连接库,请确定软件是否缺少必要文件!');
result:=false;
FreeLibrary(Handle);//释放句柄
exit;
end;
//校验是否输入合法
@funcheck:=GetProcAddress(Handle,'PCheckInputText');
iReturnValue:=funcheck(PCHAR(strProjectName),PCHAR(strText));
if iReturnValue<>1 then
begin
Register_ShowMsg('您输入的注册码不正确!');
result:=false;
end else begin
@funReg:=GetProcAddress(Handle,'PSerialRegister');
iReturnValue:=funReg(PCHAR(strText),PCHAR(strProjectName));
if iReturnValue<>1 then
begin
Register_ShowMsg('注册失败!');
result:=false;
end else result:=true;
end;
//写入注册表
FreeLibrary(Handle);//释放句柄
end;
xjq2003 2010-10-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lt8024 的回复:]
关键是这2个:char *Net_addr[]和int *addata[]
[/Quote]array of pchar
lt8024 2010-10-25
  • 打赏
  • 举报
回复
To:myxp2008
非常感谢你提供的例子,现在OnLink_Net已经成功调用,能够返回正确的数据
正准备试OnReadL_Net

OnLink_Net,调用的程序如下,已通过检验:
var
i: Integer;
IP_Addr: array[0..10]of PAnsiChar;
Ret: Integer;
Addr: array[0..19] of AnsiChar;
AddrStr: string;
begin
for i := 0 to 10 do
begin
GetMem(IP_Addr[i], 20);
end;

try
Ret := OnLink_Net(3000, 60, 1, IP_Addr);
mmo1.Lines.Add(IntToStr(Ret));

if Ret > 0 then
begin
for i := 1 to Ret do
begin
CopyMemory(@Addr[0], IP_Addr[i], 20);
end;
AddrStr := Addr;
mmo1.Lines.Add(AddrStr);
end;
finally
for i := 0 to 10 do
begin
FreeMem(IP_Addr[i]);
end;
end;
end;

还有个问题,在上面程序中,我调用后得到IP_Addr,为了获得里面的数据,我用了内存复制,CopyMemory(@Addr[0], IP_Addr[i], 20);这个占用时间
能不能IP_Addr直接定义个其他类型变量,直接代入OnLink_Net(3000, 60, 1, IP_Addr);,然后我可以直接取出数据

lt8024 2010-10-25
  • 打赏
  • 举报
回复
To:ffwin
你给出声明有几个有问题,编译不能通过.
按如下写法声明能通过编译:
function OnLink_Net(m_port: Integer; outtime: Integer; Net_Num: Integer;
Net_addr: array of PAnsiChar): Integer; stdcall; external 'NETAD.dll';
procedure OnStart_Net(TY: Integer; FS: Single; SCH: BYTE; ECH: BYTE;
GN: BYTE; TR: Integer; Kb: BYTE; Bn: Integer); stdcall; external 'NETAD.dll';
procedure OnStop_Net(TY: Integer); stdcall; external 'NETAD.dll';
function OnReadH_Net(var addata: array of SmallInt; len: LongInt): Integer;
stdcall; external 'NETAD.dll';
function OnReadL_Net(var addata: array of SmallInt; len: LongInt): Integer;
stdcall; external 'NETAD.dll';
procedure OnClose_Net; stdcall; external 'NETAD.dll';
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lt8024 的回复:]
不是我把问题复杂化了
我试过把char *Net_addr[]声明为Pchar
调用时先声明个array of char的变量,然后把变量的首地址带进去,报错
调用时先声明个string的变量,然后把串的地址带进去,函数返回值正确,但char *Net_addr[]没有获得正确的数据
另外,把char *Net_addr[]是输出变量,不是输入变量,不是什么字符串常量,他的值是返回的多个I……
[/Quote]
你不说谁知道char *Net_addr[]的值还有用?这不是输出参数,是引用传值,所以必须在函数外对参数分配空间,函数声明上面我已经给你写了,这样调用

var
APCharArray:array[0..10]of PChar;
i:integer;
begin
for i:=0 to 10 do
GetMem(APCharArray[i],xxx);//这里你自己分配xxx大小
try

OnLink_Net(整数,整数,整数,APCharArray);//调用函数

.....//其他操作
finally
for i:=0 to 10 do
FreeMem(APCharArray[i]);
end;
end;
  • 打赏
  • 举报
回复
你这不是把简单的问题复杂化了?char *Net_addr[]不过是声明了个名称为Net_addr的一维指针数组而已,实际是char*的一维数组,而char*在d中以pchar表示,所以在d中不过是个pchar的一维数组而已。

数组当然就是指针,字符常量当然也是数组,可既然有char*和pchar,何必再把字符串常量当做数组看?不是自找麻烦么?
SQLDebug_Fan 2010-10-23
  • 打赏
  • 举报
回复
给你翻译一个函数:
void WINAPI OnStop_Net(int TY);
DELPHI为
Procedure OnStop_Net(TY: Integer); stdcall;
lt8024 2010-10-23
  • 打赏
  • 举报
回复
不是我把问题复杂化了
我试过把char *Net_addr[]声明为Pchar
调用时先声明个array of char的变量,然后把变量的首地址带进去,报错
调用时先声明个string的变量,然后把串的地址带进去,函数返回值正确,但char *Net_addr[]没有获得正确的数据
另外,把char *Net_addr[]是输出变量,不是输入变量,不是什么字符串常量,他的值是返回的多个IP地址串
lt8024 2010-10-22
  • 打赏
  • 举报
回复
int WINAPI OnLink_Net(int m_port,int outtime,int Net_Num,char *Net_addr[]);
写成
PPAnsiChar = ^PAnsiChar;

function OnLink_Net(m_port: Integer; outtime: Integer; Net_Num: Integer;
Net_addr: PPAnsiChar): integer; stdcall; external 'NETAD.dll' name 'OnLink_Net';

IP_addr: PPAnsiChar;

ret := OnLink_Net(3000, 60, 1, IP_addr);
运行可以通过了

但问题我怎么获得IP_addr指向的数据

在C中是这样写的
int BN;
int m_Port,m_Num,m_Time;
char *IP_Addr[11];
for(BN=0;BN<11;BN++){
IP_Addr[BN] = (char *)malloc(sizeof(char)*20);
}
m_Port = StrToIntDef(EPort->Text,3000);
m_Num = StrToIntDef(ENum->Text,1);
m_Time = StrToIntDef(ETime->Text,2);
Net_Num=OnLink_Net(m_Port,m_Time,m_Num ,IP_Addr);


我觉得这里面有2个问题:
int WINAPI OnLink_Net(int m_port,int outtime,int Net_Num,char *Net_addr[]);
char *Net_addr[]实际上就是个指针
我只要传给他一个指针或者整数(地址)应该都能正常运行
但关键是我在delphi里面怎么获得这个指针
根据VC例子
char *IP_Addr[11];
for(BN=0;BN<11;BN++){
IP_Addr[BN] = (char *)malloc(sizeof(char)*20);
}
可以看出这个指针实际上是指向的个2维的字符数组,在delphi如果定义IP_Addr为array[0..11,0..19] of char
如何将指向IP_Addr取出来作为参数传个动态库?
还有获得的二维数组数据排列delphi和C是否一样?
  • 打赏
  • 举报
回复
给你个例子,其他数据类型看d的帮助

function OnLink_Net(m_port,outtime,Net_Num:integer;Net_addr:array of pchar);integer;stdcall;external 'net.dll'
lt8024 2010-10-22
  • 打赏
  • 举报
回复
关键是这2个:char *Net_addr[]和int *addata[]
Playmaster 2010-10-22
  • 打赏
  • 举报
回复
打开windows.pas,看看是怎么定义win32 api的,你就照葫芦画瓢。

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧