PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

时间:2022-09-29 11:29:40
由于工作需要,接手了一个同事用Delphi6.0写的通讯dll。但是这个dll在pb9.0调用后,正常运行,结束程序后会报如下错误。
PB90.EXE - 应用程序错误
“0x00000000”指令引用的“0x00000000”内存。该内存不能为“read”。

pb程序不调用dll,没有报错。所以我怀疑dll的问题大点,但是我对Delphi编译dll不是很熟悉,不清楚针对com口dll的处理哪里有问题,麻烦各位xdjm帮忙看看。可能是哪的问题?

以下贴出dll对com的初始化及释放部分

{----------------------com口初始化--------------------------------}
//com口初始化;返回值=0成功 、=1失败
function InitCom(const comid:string):integer;
begin
    //关闭com口
    if ComHandle <> 0 then
      CloseHandle(ComHandle);
    ComHandle:=createFile(pchar(comid),   //串口名
    generic_read or Generic_write,//访问模式
    0,           //共享模式,必须为0
    nil,           //安全属性指针
    open_existing,   ///找开方式必须为open_existing
    File_Flag_WRITE_THROUGH,//文件属性,操作系统不得推迟对文件的写操作
    0);

  if ComHandle = invalid_Handle_Value then   //同步方式判断串口大开是否成功
  begin
    showmessage(comid+'打开失败');
    //关闭com口
    if ComHandle <> 0 then
      CloseHandle(ComHandle);
    result := 1;
    exit;
  end;

  //设置缓冲区大小
  SetupComm(ComHandle,1024,1024);
    //设置串口的配置信息
  GetCommState(ComHandle,dcb);
  dcb.BaudRate := 19200;   //传输速率
  dcb.ByteSize := 8;      //使用的数据位数
  dcb.Parity := SPACEPARITY; //奇偶校验方法,MARKPARITY:标号校验;SPACEPARITY:空格校验
  dcb.StopBits := ONESTOPBIT; // 停止位数,ONESTOPBIT:1位停止位;ONE5STOPBITS:1.5位停止位;TWOSTOPBITS:2位停止位

  if not SetCommState(ComHandle,dcb) then
  begin
    //关闭com口
    if ComHandle <> 0 then
      CloseHandle(ComHandle);
    result := 1;
    exit;
  end;

  PurgeComm(ComHandle,(PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR));
  //设置串口的超时时间
  GetCommTimeouts(ComHandle,CommTimeouts);
  CommTimeouts.ReadIntervalTimeout := 100;
  CommTimeouts.ReadTotalTimeoutMultiplier := 50;
  CommTimeouts.ReadTotalTimeoutConstant := 500;
  CommTimeouts.WriteTotalTimeoutMultiplier := 50;
  CommTimeouts.WriteTotalTimeoutConstant := 500;
  SetCommTimeOuts(ComHandle,CommTimeouts);
  result:=0;

end;
{------------------------------------------------------------------}

{------------------------初始化DLL---------------------------------}
//初始化变量=0成功;=1失败  超时时间
function Init(const CDT:integer):integer;
begin
  CallDelayTime:=CDT;
  result:=0;
end;
{------------------------------------------------------------------}

{------------------------释放DLL---------------------------------}
//释放对象 =0成功;=1失败
  function UnInit:integer;stdcall;
begin
  //关闭com口
  if ComHandle <> 0 then
    CloseHandle(ComHandle);
  result:=0;
end;
{------------------------------------------------------------------}

29 个解决方案

#1


你把你调用DLL 的语句贴出来看看,包括申明DLL函数

#2


在Global External Functions中

//主机初始化变量
function integer Init(integer CDT) library "Project2.dll"
//释放对象 =0成功;=1失败
function integer UnInit() library "Project2.dll"
//主机初始化com口函数 =0成功;=1失败
function integer InitCom(string comid) library "Project2.dll"


在实际调用中,初始化如下:
if s_sendmark = '1' then
rtn = Init(200)
if rtn <> 0 then
messagebox('提示','初始化发卡器DLL失败!')
end if
rtn = InitCom(s_comid)
if rtn <> 0 then
messagebox('提示',s_comid + '串口初始化失败!')
end if
end if

释放
l_rtn = UnInit()
if l_rtn <> 0 then
messagebox('提示','释放发卡器通讯的Dll对象失败!')
end if

#3


需要声明以下函数才行吧:
InitCom()
SetupComm()
CloseHandle()
GetCommState()
PurgeComm()
Init()
UnInit()

#4


还有什么其它见解没?帮兄弟我看看! PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#5


我估计是你调用的问题,而不是DLL的问题!
引用 4 楼 snowwolf_119 的回复:
还有什么其它见解没?帮兄弟我看看!

#6


我也有这个问题....等待解决中....

#7


定义
function Ulong Init(integer CDT) library "Project2.dll"
function Ulong UnInit() library "Project2.dll"
function Ulong InitCom(string comid) library "Project2.dll"

试试,出现这样的问题一般是访问了非法内存的缘故!



#8


引用 7 楼 xuam 的回复:
定义
function Ulong Init(integer CDT) library "Project2.dll"
function Ulong UnInit() library "Project2.dll"
function Ulong InitCom(string comid) library "Project2.dll"

试试,出现这样的问题一般是访问了非法内存的缘故!

……

试了,结果是一样的。

#9


可以DEBUG 看看,具体是访问哪个地方出错!

引用 8 楼 snowwolf_119 的回复:
引用 7 楼 xuam 的回复:
定义
function Ulong Init(integer CDT) library "Project2.dll"
function Ulong UnInit() library "Project2.dll"
function Ulong InitCom(string comid) library "Project2.dll"

试试,出现这样的问题……

#10


不是程序运行时出错,是退出之后报错!!要是能debug,就不上csdn了!! PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#11


我不解的是我不调用dll的时候,不报错。
调用的时候,执行dll中的方法,也不报错。但是在退出之后,却莫名地出了读取错误。
难道pb在调用dll后,就要在结束的时候再莫名的读取什么东西??
不解?????
等待之情人的降临……………………………………………………………… PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#12


function UnInit:integer;stdcall;
有可能这个的问题.
还有把pb打上最新的补丁试试!
引用 10 楼 snowwolf_119 的回复:
不是程序运行时出错,是退出之后报错!!要是能debug,就不上csdn了!!

#13


参考:
http://blog.csdn.net/feixianzhi/archive/2005/03/01/306271.aspx

引用 11 楼 snowwolf_119 的回复:
我不解的是我不调用dll的时候,不报错。
调用的时候,执行dll中的方法,也不报错。但是在退出之后,却莫名地出了读取错误。
难道pb在调用dll后,就要在结束的时候再莫名的读取什么东西??
不解?????
等待之情人的降临………………………………………………………………

#14


版本是8366,应该是最新的。
目前程序是调用dll,不执行其具体方法。
只执行初始化和释放,就在结束之后报错。
郁闷中……………………

#15


8836,写错了。呵呵 PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#16


写出你的调用程序看看,大多数是变量定义错误引起的,定义时要严格安装dll的定义。

#17


rtn = InitCom(s_comid)
中的s_comid要指定长度
比如
s_comid = space(1000)

#18


引用 17 楼 xys_777 的回复:
rtn = InitCom(s_comid)
中的s_comid要指定长度
比如
s_comid = space(1000)

目前是确定了具体长度,也是同样的不解决问题。 什么情况??? PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#19


目前是不执行dll中的具体方法,只是初始化和释放就提示错误。
为了更方便大家理解,我把简单运行中的代码贴出,麻烦xdjm帮忙看看。 PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

在Global Variables中声明的变量
string s_comid,s_brate,s_sendmark


主窗体open()事件
integer rtn
long l_setovertime,l_callovertime

//读取ini文件信息
s_comid= ProfileString("config.ini", "porperties", "comid","")
s_brate= ProfileString("config.ini", "porperties", "brate","")
s_sendmark= ProfileString("config.ini", "porperties", "sendmark","")
l_setovertime = Profileint("config.ini", "communication", "setovertime",0)
l_callovertime = Profileint("config.ini", "communication", "callovertime",0)

if s_sendmark = '1' then
rtn = Init(500)
if rtn <> 0 then
messagebox('提示','初始化通讯DLL失败!')
end if
rtn = InitCom(s_comid)
if rtn <> 0 then
messagebox('提示',s_comid + '串口初始化失败!')
end if
end if


主窗体close()事件
long l_rtn
l_rtn = UnInit()
if l_rtn <> 0 then
messagebox('提示','释放串口通讯的Dll对象失败!')
end if

#20


在DELPHI里那个ComHandle   ,你在PB里对应的变量是哪个?

#21


引用 20 楼 xuam 的回复:
在DELPHI里那个ComHandle ,你在PB里对应的变量是哪个?

没有对应,pb没有直接处理com口,完全是dll处理的。

#22


一般来说,这种问题是DLL占用的资源没有释放引起的。
一个好的dll应该提供释放资源的方法调用。
如果是你自己写的dll,那么请检查是否释放资源。
如果是使用别人的dll,那么请检查是否有释放资源的方法而你没有调用。

#23


delphi 我不是很熟悉,dll也是曾经的同事写的,本身对Delphi也是略懂个皮毛。

以下是dll所使用的,麻烦各位xdjm帮俺看看,哪些需要释放呢?
type
  GlobalBuf = record //收发全局变量记录
    sData:array[0..1023] of byte; //全局发送缓冲区
    iData:array[0..1023] of byte; //全局接收缓冲区
    writeLen,factWriteLen,readLen,factReadLen:DWORD;//待发长度、实发长度、待收长度、实收长度
  end;
var
  dcb : TDCB;  //com口的dcb
  CommTimeouts : _COMMTIMEOUTS; //com口的超时变量
  ComHandle:THandle;//com口句柄
  CallDelayTime:longint;//通讯超时时间
  //超时时间 (机床)
  CallDelayTime1:longint; //刻度
  CallDelayTime2:longint; //电流
  CallDelTimeMark:integer; //刻度电流标识位  1为刻度 2为电流
  RGlobalBuf:GlobalBuf;//定义全局变量记录

#24


PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!
石沉大海了?不是吧?

#25


比较难判断这个问题,必须和DLL那边共同调试,
要么把DLL部分写成标准的VC++函数来调用!
引用 24 楼 snowwolf_119 的回复:
石沉大海了?不是吧?

#26


这个问题确实有点不好处理,由于它出现在我抓不到的位置。所以才上网,希望有遇到过类似问题的朋友,给点处理意见,或者说通过什么步骤能找到问题的所在。VC++这个哥们还真不懂,没法用此方式来调试。
在此先谢谢大家了!! PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#27


Delphi不懂,不过这些自己变量应该不是问题所在,一般来说,有两种可能
1、VC中new了,或者注册了内存、指针,没有释放的,可能引起问题;
2、申请了系统资源,例如初始化COM口的代码,例如InitCom(xx,xx);没有释放的,可能会引起这个问题。

希望能帮到你。

#28


又沉了?? PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#29


还是问题,不过谢谢大家了。结贴!!!

#1


你把你调用DLL 的语句贴出来看看,包括申明DLL函数

#2


在Global External Functions中

//主机初始化变量
function integer Init(integer CDT) library "Project2.dll"
//释放对象 =0成功;=1失败
function integer UnInit() library "Project2.dll"
//主机初始化com口函数 =0成功;=1失败
function integer InitCom(string comid) library "Project2.dll"


在实际调用中,初始化如下:
if s_sendmark = '1' then
rtn = Init(200)
if rtn <> 0 then
messagebox('提示','初始化发卡器DLL失败!')
end if
rtn = InitCom(s_comid)
if rtn <> 0 then
messagebox('提示',s_comid + '串口初始化失败!')
end if
end if

释放
l_rtn = UnInit()
if l_rtn <> 0 then
messagebox('提示','释放发卡器通讯的Dll对象失败!')
end if

#3


需要声明以下函数才行吧:
InitCom()
SetupComm()
CloseHandle()
GetCommState()
PurgeComm()
Init()
UnInit()

#4


还有什么其它见解没?帮兄弟我看看! PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#5


我估计是你调用的问题,而不是DLL的问题!
引用 4 楼 snowwolf_119 的回复:
还有什么其它见解没?帮兄弟我看看!

#6


我也有这个问题....等待解决中....

#7


定义
function Ulong Init(integer CDT) library "Project2.dll"
function Ulong UnInit() library "Project2.dll"
function Ulong InitCom(string comid) library "Project2.dll"

试试,出现这样的问题一般是访问了非法内存的缘故!



#8


引用 7 楼 xuam 的回复:
定义
function Ulong Init(integer CDT) library "Project2.dll"
function Ulong UnInit() library "Project2.dll"
function Ulong InitCom(string comid) library "Project2.dll"

试试,出现这样的问题一般是访问了非法内存的缘故!

……

试了,结果是一样的。

#9


可以DEBUG 看看,具体是访问哪个地方出错!

引用 8 楼 snowwolf_119 的回复:
引用 7 楼 xuam 的回复:
定义
function Ulong Init(integer CDT) library "Project2.dll"
function Ulong UnInit() library "Project2.dll"
function Ulong InitCom(string comid) library "Project2.dll"

试试,出现这样的问题……

#10


不是程序运行时出错,是退出之后报错!!要是能debug,就不上csdn了!! PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#11


我不解的是我不调用dll的时候,不报错。
调用的时候,执行dll中的方法,也不报错。但是在退出之后,却莫名地出了读取错误。
难道pb在调用dll后,就要在结束的时候再莫名的读取什么东西??
不解?????
等待之情人的降临……………………………………………………………… PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#12


function UnInit:integer;stdcall;
有可能这个的问题.
还有把pb打上最新的补丁试试!
引用 10 楼 snowwolf_119 的回复:
不是程序运行时出错,是退出之后报错!!要是能debug,就不上csdn了!!

#13


参考:
http://blog.csdn.net/feixianzhi/archive/2005/03/01/306271.aspx

引用 11 楼 snowwolf_119 的回复:
我不解的是我不调用dll的时候,不报错。
调用的时候,执行dll中的方法,也不报错。但是在退出之后,却莫名地出了读取错误。
难道pb在调用dll后,就要在结束的时候再莫名的读取什么东西??
不解?????
等待之情人的降临………………………………………………………………

#14


版本是8366,应该是最新的。
目前程序是调用dll,不执行其具体方法。
只执行初始化和释放,就在结束之后报错。
郁闷中……………………

#15


8836,写错了。呵呵 PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#16


写出你的调用程序看看,大多数是变量定义错误引起的,定义时要严格安装dll的定义。

#17


rtn = InitCom(s_comid)
中的s_comid要指定长度
比如
s_comid = space(1000)

#18


引用 17 楼 xys_777 的回复:
rtn = InitCom(s_comid)
中的s_comid要指定长度
比如
s_comid = space(1000)

目前是确定了具体长度,也是同样的不解决问题。 什么情况??? PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#19


目前是不执行dll中的具体方法,只是初始化和释放就提示错误。
为了更方便大家理解,我把简单运行中的代码贴出,麻烦xdjm帮忙看看。 PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

在Global Variables中声明的变量
string s_comid,s_brate,s_sendmark


主窗体open()事件
integer rtn
long l_setovertime,l_callovertime

//读取ini文件信息
s_comid= ProfileString("config.ini", "porperties", "comid","")
s_brate= ProfileString("config.ini", "porperties", "brate","")
s_sendmark= ProfileString("config.ini", "porperties", "sendmark","")
l_setovertime = Profileint("config.ini", "communication", "setovertime",0)
l_callovertime = Profileint("config.ini", "communication", "callovertime",0)

if s_sendmark = '1' then
rtn = Init(500)
if rtn <> 0 then
messagebox('提示','初始化通讯DLL失败!')
end if
rtn = InitCom(s_comid)
if rtn <> 0 then
messagebox('提示',s_comid + '串口初始化失败!')
end if
end if


主窗体close()事件
long l_rtn
l_rtn = UnInit()
if l_rtn <> 0 then
messagebox('提示','释放串口通讯的Dll对象失败!')
end if

#20


在DELPHI里那个ComHandle   ,你在PB里对应的变量是哪个?

#21


引用 20 楼 xuam 的回复:
在DELPHI里那个ComHandle ,你在PB里对应的变量是哪个?

没有对应,pb没有直接处理com口,完全是dll处理的。

#22


一般来说,这种问题是DLL占用的资源没有释放引起的。
一个好的dll应该提供释放资源的方法调用。
如果是你自己写的dll,那么请检查是否释放资源。
如果是使用别人的dll,那么请检查是否有释放资源的方法而你没有调用。

#23


delphi 我不是很熟悉,dll也是曾经的同事写的,本身对Delphi也是略懂个皮毛。

以下是dll所使用的,麻烦各位xdjm帮俺看看,哪些需要释放呢?
type
  GlobalBuf = record //收发全局变量记录
    sData:array[0..1023] of byte; //全局发送缓冲区
    iData:array[0..1023] of byte; //全局接收缓冲区
    writeLen,factWriteLen,readLen,factReadLen:DWORD;//待发长度、实发长度、待收长度、实收长度
  end;
var
  dcb : TDCB;  //com口的dcb
  CommTimeouts : _COMMTIMEOUTS; //com口的超时变量
  ComHandle:THandle;//com口句柄
  CallDelayTime:longint;//通讯超时时间
  //超时时间 (机床)
  CallDelayTime1:longint; //刻度
  CallDelayTime2:longint; //电流
  CallDelTimeMark:integer; //刻度电流标识位  1为刻度 2为电流
  RGlobalBuf:GlobalBuf;//定义全局变量记录

#24


PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!
石沉大海了?不是吧?

#25


比较难判断这个问题,必须和DLL那边共同调试,
要么把DLL部分写成标准的VC++函数来调用!
引用 24 楼 snowwolf_119 的回复:
石沉大海了?不是吧?

#26


这个问题确实有点不好处理,由于它出现在我抓不到的位置。所以才上网,希望有遇到过类似问题的朋友,给点处理意见,或者说通过什么步骤能找到问题的所在。VC++这个哥们还真不懂,没法用此方式来调试。
在此先谢谢大家了!! PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#27


Delphi不懂,不过这些自己变量应该不是问题所在,一般来说,有两种可能
1、VC中new了,或者注册了内存、指针,没有释放的,可能引起问题;
2、申请了系统资源,例如初始化COM口的代码,例如InitCom(xx,xx);没有释放的,可能会引起这个问题。

希望能帮到你。

#28


又沉了?? PB9.0调用Delphi6.0编译的dll 结束程序报错问题!!

#29


还是问题,不过谢谢大家了。结贴!!!