Delphi7.0调用VC写的动态库问题,请大侠帮忙

guoyabin2000 2011-09-10 12:50:03
各位大侠好:
小弟现在用Delphi调用VC写的一个动态库,结果总是出现内存访问问题,据我初步判断是调用规约的问题,可我试了多种方法都没有解决,请大侠帮忙!
VC的函数定义如下:
extern "C" {
__declspec( dllexport ) int WINAPI OpenCommPort(char cComPort);
}
请大侠帮忙看看,Delphi该怎么写?急,在线等。
...全文
167 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
SxSQuid 2011-09-13
  • 打赏
  • 举报
回复

__declspec( dllexport ) int WINAPI OpenCommPort(char cComPort);

delphi

function OpenCommPort(cComPort: Char): Integer; cdecl external DllName;
SxSQuid 2011-09-13
  • 打赏
  • 举报
回复
调用C++函数.定义尾部须加上 cdecl;
guoyabin2000 2011-09-12
  • 打赏
  • 举报
回复
各位大侠,图片怎么加不进去呀。我把图片上的内容写出来吧。
第一个图片提示是:
Access violation at address 004042CE in module 'Hand_ReadMeter.exe'.Read of address CCCCCCC4.
第二个图片是:
CPU
Thread #4064
ntdll.KiFastSystemCallRet:
7C92EB94 C3 ret
7C92EB95 8DA42400000000 lea esp,[esp+$00000000]
7C92EB9C 8D642400 lea esp,[esp+$00]
7C92EBA0 90 nop
7C92EBA1 90 nop
7C92EBA2 90 nop
7C92EBA3 90 nop
7C92EBA4 90 nop
ZyxIp 2011-09-11
  • 打赏
  • 举报
回复
D在调用时不能使用 String,传入的参数如果要是指针的话,先要将内存分配好。

在就是问问题时不要以为你随便说个没头没尾的话大家就能知道你在说什么。
浩南_哥 2011-09-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 guoyabin2000 的回复:]

谢谢楼上的各位大侠,小弟不胜感激。上面说的方法我都试了,还是不行。对方给的VC写的函数里面有很多的函数,调用的时候有些出现内存访问错误,有些没有,我还发现一个现象,凡是函数是输入的char*都没有问题,char*是函数用作输出用的,有些函数就出现内存访问问题,有些就没有出现。但是我用VC写个程序调用这个动态库就没有这个问题。
[/Quote]
你光说有些有问题,你也不给 出哪些有问题,包括VC原型,你是怎么写的声明
山东蓝鸟贵薪 2011-09-11
  • 打赏
  • 举报
回复
可能是参数有问题吧
guoyabin2000 2011-09-11
  • 打赏
  • 举报
回复
谢谢楼上的各位大侠,小弟不胜感激。上面说的方法我都试了,还是不行。对方给的VC写的函数里面有很多的函数,调用的时候有些出现内存访问错误,有些没有,我还发现一个现象,凡是函数是输入的char*都没有问题,char*是函数用作输出用的,有些函数就出现内存访问问题,有些就没有出现。但是我用VC写个程序调用这个动态库就没有这个问题。
rainychan2009 2011-09-11
  • 打赏
  • 举报
回复
function OpenCommPort(cComPort: Char): Integer; cdecl;
guoyabin2000 2011-09-11
  • 打赏
  • 举报
回复
楼上几位大侠说的对,小弟现在就把代码贴出来。

这是VC写的DLL
// -----------串口通信的功能函数-------------
extern "C" {
__declspec( dllexport ) int WINAPI OpenCommPort(char cComPort);
__declspec( dllexport ) int WINAPI CloseCommPort(void);
__declspec( dllexport ) int WINAPI SetComMode(long BaudRate,char ByteSize, char Parity, char StopBits);
__declspec( dllexport ) int WINAPI PutPack(char * TxData, unsigned int TxLen, unsigned int TxCount);
__declspec( dllexport ) int WINAPI GetPack(char * RxData);
__declspec( dllexport ) long WINAPI SendClientReq(int ReqType ,char * ExFileName);
__declspec( dllexport ) int WINAPI OpenExFile(int OpenType ,char * HOF);
__declspec( dllexport ) int WINAPI ReadExFile(char * RxBuff);
__declspec( dllexport ) int WINAPI CloseExFile(int CloseType);
__declspec( dllexport ) int WINAPI WriteExFile(char * RxBuff, int iRLen);
__declspec( dllexport ) void WINAPI ErrorString(int iErrCode, char * cErrMsg);
__declspec( dllexport ) int WINAPI GetRetry(void);
__declspec( dllexport ) int WINAPI MkDir(char *filepath,unsigned int iPort, long iBaud); //创建目录 参数:文件名,端口,波特率
__declspec( dllexport ) int WINAPI SetDir(char *filepath,unsigned int iPort, long iBaud); //设置机器当前的目录 参数:路径,端口,波特率
__declspec( dllexport ) int WINAPI SetHtTime(unsigned int iPort, long iBaud);//设置HT设备的时间为系统当前时间,返回0表示设置成功

}
//以下功能必须抄表器在文件服务上
__declspec( dllexport ) long WINAPI CreateConnect(long iBaud,int iPort,int iSerialNo,int iDelay,int IsNew);
__declspec( dllexport ) void WINAPI DisConnect(long Handle);
__declspec( dllexport ) int WINAPI ExFGet(char PCFile[], char HTFile[], unsigned int iPort, long iBaud, unsigned iSerialNo);//上装文件 参数: 电脑文件 ,掌上电脑文件 ,端口 ,波特率 ,0
__declspec( dllexport ) int WINAPI ExFPut(char PCFile[], char HTFile[], unsigned int iPort, long iBaud, unsigned iSerialNo);//下传文件 参数: 电脑文件(支持路径),掌上电脑文件,端口 ,波特率 ,0
__declspec( dllexport ) long WINAPI wSetDateTime(char szDate[],char szTime[],unsigned int iPort,long iBaud);//设机器的日期和时间
__declspec( dllexport ) long WINAPI wGetDateTime(char *szDate, char *szTime,unsigned int iPort,long iBaud); //取得机器的日期和时间 日期格式: 20020312 时间格式:13:12:02
__declspec( dllexport ) long WINAPI HTMessage(char *iserial,char *itpye,unsigned int iPort,long iBaud); //取得机器的机身号和类型 例如 00002002,2800,
__declspec( dllexport ) long WINAPI GetHtFile(char *filebuff,unsigned int iPort,long iBaud); //取得HT 的文件放在FILEBUFF 中 每个文件的长度不超过12字节,返回是文件的数目
__declspec( dllexport ) long WINAPI DelHtFile(char filename[],unsigned int iPort,long iBaud); //删除文件 FILE 文件名 ,0 返回成功
__declspec( dllexport ) long WINAPI GetHtSN(unsigned int iPort, long iBaud); //取机器的序号 返回是序列号 iBaud 波特率 iPort端口
__declspec( dllexport ) long WINAPI ExitHTSevr(unsigned int iPort, long iBaud); //退出文件服务器
__declspec( dllexport ) long WINAPI HTTest(unsigned int iPort, long iBaud); //检查机器是否存在, 存在返回0
__declspec( dllexport ) void WINAPI GetDllInfo(char *ver,char *modidate); //取得版本和修改日前 如 "V1.0" ,"2003.12.01"
__declspec( dllexport ) long WINAPI HT26XXFM(unsigned int iPort, long iBaud); //格式化26系列,返回是0 表示命令正常发出去



当Delphi写成如下方式时:
function OpenCommPort(cComPort: Char): Integer; stdcall;
function CloseCommPort(): Integer; stdcall;
function SetComMode(BaudRate: Integer; ByteSize: Char; Parity: Char; StopBits: Char): Integer; stdcall;
function PutPack(TxData: PChar; TxLen: Cardinal; TxCount: Cardinal): Integer; stdcall;
function GetPack(RxData: PChar): Integer; stdcall;
function SendClientReq(ReqType: Integer; ExFileName: PChar): Integer; stdcall;
function OpenExFile(OpenType: Integer; HOF: PChar): Integer; stdcall;
function ReadExFile(RxBuff: PChar): Integer; stdcall;
function CloseExFile(CloseType: Integer): Integer; stdcall;
function WriteExFile(RxBuff: PChar; iRLen: Integer): Integer; stdcall;
procedure ErrorString(iErrCode: Integer; cErrMsg: PChar); stdcall;
function GetRetry(): Integer; stdcall;
function MkDir(filepath: PChar; iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function SetDir(filepath: PChar; iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function SetHtTime(iPort: Cardinal; iBaud: Integer): Integer; stdcall;

//以下功能必须抄表器在文件服务上
function CreateConnect(iBaud: Integer; iPort: Integer; iSerialNo: Integer; iDelay: Integer; IsNew: Integer): Integer; stdcall;
procedure DisConnect(Handle: Integer); stdcall;
function ExFGet(PCFile: PChar; HTFile: PChar; iPort: Cardinal; iBaud: Integer; iSerialNo: Cardinal): Integer; stdcall;
function ExFPut(PCFile: PChar; HTFile: PChar; iPort: Cardinal; iBaud: Integer; iSerialNo: Cardinal): Integer; stdcall;
function wSetDateTime(szDate: PChar; szTime: PChar; iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function wGetDateTime(szDate: PChar; szTime: PChar; iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function HTMessage(iserial: PChar; itype: PChar; iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function GetHtFile(filebuff: PChar; iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function DelHtFile(filename: PChar; iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function GetHtSN(iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function ExitHTSevr(iPort: Cardinal; iBaud: Integer): Integer; stdcall;
function HTTest(iPort: Cardinal; iBaud: Integer): Integer; stdcall;
procedure GetDllInfo(ver: PChar; modidate: PChar); stdcall;
function HT26XXFM(iPort: Cardinal; iBaud: Integer): Integer; stdcall;

implementation

const
HT2900_32 = 'ht32dll.dll';

//use general function
function OpenCommPort; stdcall; external HT2900_32 name 'OpenCommPort';
function CloseCommPort; stdcall; external HT2900_32 name 'CloseCommPort';
function SetComMode; stdcall; external HT2900_32 name 'SetComMode';
function PutPack; stdcall; external HT2900_32 name 'PutPack';
function GetPack; stdcall; external HT2900_32 name 'GetPack';
function SendClientReq; stdcall; external HT2900_32 name 'SendClientReq';
function OpenExFile; stdcall; external HT2900_32 name 'OpenExFile';
function ReadExFile; stdcall; external HT2900_32 name 'ReadExFile';
function CloseExFile; stdcall; external HT2900_32 name 'CloseExFile';
function WriteExFile; stdcall; external HT2900_32 name 'WriteExFile';
procedure ErrorString; stdcall; external HT2900_32 name 'ErrorString';
function GetRetry; stdcall; external HT2900_32 name 'GetRetry';
function MkDir; stdcall; external HT2900_32 name 'MkDir';
function SetDir; stdcall; external HT2900_32 name 'SetDir';
function SetHtTime; stdcall; external HT2900_32 name 'SetHtTime';
//以下功能必须抄表器在文件服务上
function CreateConnect; stdcall; external HT2900_32 name 'CreateConnect';
procedure DisConnect; stdcall; external HT2900_32 name 'DisConnect';
function ExFGet; stdcall; external HT2900_32 name 'ExFGet';
function ExFPut; stdcall; external HT2900_32 name 'ExFPut';
function wSetDateTime; stdcall; external HT2900_32 name 'wSetDateTime';
function wGetDateTime; stdcall; external HT2900_32 name 'wGetDateTime';
function HTMessage; stdcall; external HT2900_32 name 'HTMessage';
function GetHtFile; stdcall; external HT2900_32 name 'GetHtFile';
function DelHtFile; stdcall; external HT2900_32 name 'DelHtFile';
function GetHtSN; stdcall; external HT2900_32 name 'GetHtSN';
function ExitHTSevr; stdcall; external HT2900_32 name 'ExitHTSevr';
function HTTest; stdcall; external HT2900_32 name 'HTTest';
procedure GetDllInfo; stdcall; external HT2900_32 name 'GetDllInfo';
function HT26XXFM; stdcall; external HT2900_32 name 'HT26XXFM';

我自己的Delphi运行程序代码如下:
procedure TInceptDataForm.bbtnExplorerClick(Sender: TObject);

function ParseListBuffer(ListBuff: PChar): String;
var
//strName: array[0..15] of char;
strName: String;
i: Integer;
begin
strName := '';
for i := 0 to 12 do
begin
strName := strName + ListBuff[i+9];
//strName[i] := ListBuff[i+9];
end;
Result := strName;
end;

var
iComPort, iBaudRate, iResult: Integer;
Buffer: array[0..256] of Char;
i, j, CountOfName: Integer;
ListBuffer: array[0..50] of Char;
strHTName: String;
begin
if Trim(cbbComPort.Text) = '' then
begin
ShowMessage('请先选择好通讯端口!');
cbbComPort.SetFocus;
Exit;
end;
iComPort := StrToCommPort(Trim(cbbComPort.Text));

iBaudRate := StrToInt(Trim(cbbBaudRate.Text));

iResult := OpenCommPort(char(iComPort));
if iResult = 0 then //打开通讯端口成功
begin
iResult := SetComMode(iBaudRate, Char(8), Char(0), Char(0));
if iResult = 0 then //设置通讯方式成功
begin
iResult := SendClientReq(_ListReq, ''); //发送请求
if iResult = 0 then
begin
iResult := OpenExFile(_4Read, Buffer); //打开目录
if iResult > 0 then
begin
//
j := 0;
CountOfName := 0;
iResult := ReadExFile(Buffer); //开始读目录
while iResult > 0 do
begin
for i := 0 to iResult - 1 do
begin
ListBuffer[j] := Buffer[i];
inc(j);
if j >= 21 then
begin
ListBuffer[j] := chr(0);
strHTName := ParseListBuffer(ListBuffer);
lbHTFileName.Items.Add(strHTName);
inc(CountOfName);

j := 0;
end;
end;
iResult := ReadExFile(Buffer);
end;
CloseExFile(_4Read);
end;
end;
end;
CloseCommPort();
end;
lbHTFileName.Items.Delete(CountOfName-1);
//ShowMessage('1111111');
end;

在上面语句
iResult := ReadExFile(Buffer); //开始读目录
中有如下图片提示。


如果上面动态链接库中的stdcall全部该成cdecl
结果在调试的时候程序运行上面的代码,也没有反应了出现下面的情况:

山东蓝鸟贵薪 2011-09-10
  • 打赏
  • 举报
回复
占个位置学习一下
顶顶帖子
学习学习先
Jekhn 2011-09-10
  • 打赏
  • 举报
回复
Jekhn 2011-09-10
  • 打赏
  • 举报
回复
VC编写的DLL:

#include <stdio.h>
#include <windows.h>

extern "C"
{
_declspec(dllexport) int _cdecl getSum(int x, int y);
_declspec(dllexport) int _cdecl getMax(int x, int y);
_declspec(dllexport) int _cdecl getMin(int x, int y);

}

int getSum(int x, int y)
{
return x + y;
}

int getMax(int x, int y)
{
return (x>y) ? x : y;
}

int getMin(int x, int y)
{
return (x<y) ? x : y;
}

extern "C" BOOL APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
MessageBox(0,"Dll Process Attach.","Dll Main",0);
}
else
if (dwReason == DLL_PROCESS_DETACH)
{
MessageBox(0,"Dll Process Detach.","Dll Main",0);
}
return TRUE;
}


Delphi调用:


unit unitMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

function getSum(x,y:Integer):Integer;cdecl; external 'DllDemo.dll';
function getMax(x,y:Integer):Integer;cdecl; external 'DllDemo.dll';
function getMin(x,y:Integer):Integer;cdecl; external 'DllDemo.dll';

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
a,b,c: Integer;
begin
a := 5;
b := 4;
c := getSum(a,b);
ShowMessage('sum: ' + IntToStr(c));
c := getMax(a,b);
ShowMessage('max: ' + IntToStr(c));
c := getMin(a,b);
ShowMessage('min: ' + IntToStr(c));
end;

end.
贝隆 2011-09-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fontomas 的回复:]
函数名前面加个 __stdcall 试试
[/Quote]
+1
春风老少年 2011-09-10
  • 打赏
  • 举报
回复
函数名前面加个 __stdcall 试试
bdmh 2011-09-10
  • 打赏
  • 举报
回复
约定 cdecl

function OpenCommPort(cComPort:AnsiChar);

16,749

社区成员

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

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