是三层高手的,您就进!十万火急,救命呀!!!!!

danny_ht204 2003-08-22 11:17:24
中间层系统:windows 2000
客户端系统:windwos 2000
本人现正编写一个三层程序.使用DCOM方式.
中间层的主要功能就是根据客户端的请求,调用中间层上的外挂DLL程序完成操作.
客户端有多个,可以同时并发调用中间层.
具体流程就是:
客户端A调用中间层COM,并激发中间层COM的方法FUNC,由中间层方法FUNC调用外挂DLL程序,DLL程序实现与数据服务器SERVER进行多线程的SOCKET通讯.通讯完毕以后,DLL程序自动退出.
客户端有多个,不定时调用,因此就可以出现两个以上的客户端同时调用.
对于DCOM来说,可以支持多用户同时调用.
现在关键就是在DCOM调用外挂程序DLL是出现问题.
由于WINDOWS只是在内存做一个DLL的映射.
当第一个客户端激发中间层调用DLL程序时,SOCKET通讯正常.
如果此时第二个客户端又激发中间层调用DLL程序时,又激发新的SOCKET通讯.
也就是两个DLL并行运行.SOCKET通讯可以正常通讯.
但是,
当其中任意一个SOCKET通讯完成时,第二个DLL程序自动退出,但是第一个DLL程序不管怎么样,始终退不出来.
但强行关闭时,DCOM会报错"无效的窗口句柄".
那位大侠知道,请帮帮忙
...全文
24 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
shsunb 2003-09-09
  • 打赏
  • 举报
回复
说到底就是个全局变量问题,建议搂主将所有的delphi产生的窗体全局变量都删除,你会感觉代码如洗面奶般清爽!
charlish 2003-09-03
  • 打赏
  • 举报
回复
楼上的大侠的这个释放窗体会有问题,你应该让它改成:
procedure showdll();stdcall;
Var
Form1:TForm1;
begin
form1:=tform1.Create(Nil);
try
form1.ShowModal;
finally
freeandnil(form1);
end;
end;
猛禽 2003-08-28
  • 打赏
  • 举报
回复
不好意思,时间有限,只能提供思路。

基本上除了form1.showmodal后应该加一句form1.free以外,其它没什么错误,如果还不行,则问题可能出在这种方法根本行不通。

因为VCL并不是线程安全的,至少Application是一个全局变量,这个无法避免。

就此例来说,Application并不是必须的。

所以你改成这样试试:

procedure showdll();stdcall;
Var
Form1:TForm1;
begin
form1:=tform1.Create(Nil);
form1.ShowModal;
form1.free;
end;

我没测试过,不保证能行,good luck
猛禽 2003-08-27
  • 打赏
  • 举报
回复
改成这样
var
// Form1: TForm1;
procedure showdll(ahandle : thandle);stdcall;
implementation

{$R *.DFM}
procedure showdll(ahandle : thandle);stdcall;
Var
Form1:TForm1;
begin
application.Handle:=ahandle;
form1:=tform1.Create(application);
form1.ShowModal;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Self.Close;
end;
猛禽 2003-08-27
  • 打赏
  • 举报
回复
很明显,你的DLL代码中
var
Form1: TForm1;
是一个全局变量,这样两个客户端连过来创建的窗体对象都存在这里,后面一个客户端连接就会把前一个客户端连接保存的窗体变量冲掉,所以只有后面一个窗体是正常的,前一个就会出错。
danny_ht204 2003-08-27
  • 打赏
  • 举报
回复
呵呵,不好意思
我想楼上的仁兄能否真真实实的测一下该程序。
猛禽 2003-08-27
  • 打赏
  • 举报
回复
呵呵,忘记了,前面的VAR也要注释掉:)
danny_ht204 2003-08-27
  • 打赏
  • 举报
回复
我不知道楼上这位仁兄是否测过该程序。
按照你所说的写法,会出现出错。
错误的地方,正好是你所注释的这句:// Form1: TForm1;

不过还是很感谢楼上的仁兄给了我提示。
目前我已经解决了我测试程序所碰到的问题。
正准备正式在生产机上面测试程序。
等测试出来了在发贴。
danny_ht204 2003-08-26
  • 打赏
  • 举报
回复
我也试过用静态的DLL,但是问题是一样的
rwdx 2003-08-26
  • 打赏
  • 举报
回复
使用静态调用DLL看看
danny_ht204 2003-08-26
  • 打赏
  • 举报
回复

我做了一个很简单的测试程序
只是做显示窗体,然后关闭
代码如下:

中间层的方法

procedure tform1.calldll;
var
hLibrary : THANDLE;
PortValue : integer;
showdll : tshowdll;
begin
try
hLibrary:=GetModuleHandle('APR.DLL');
showmessage(inttostr(hLibrary));
if (hLibrary=0) then //hLibrary:=LoadLibrary('APR.DLL'); //加载DLL
hLibrary:=LoadLibraryEx('apr.dll',1,0);
@showdll:=GetProcAddress(hLibrary,'showdll');
//检取成功则调用
showdll(application.Handle);
hLibrary:=GetModuleHandle('APR.DLL');
showmessage(inttostr(hLibrary));
// FreeLibraryAndExitThread(hLibrary,0);
except
on E: Exception do showmessage(E.Message);
end;
end;

被调用程序
unit a;

interface

uses
Windows, Messages, Forms,
StdCtrls, Classes, Controls;

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

var
Form1: TForm1;
procedure showdll(ahandle : thandle);stdcall;
implementation

{$R *.DFM}
procedure showdll(ahandle : thandle);stdcall;
begin
application.Handle:=ahandle;
form1:=tform1.Create(application);
form1.ShowModal;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Close;
end;

end.
wyr521 2003-08-23
  • 打赏
  • 举报
回复
不好意思,我不会
myling 2003-08-22
  • 打赏
  • 举报
回复
退出时有代码吗?

贴出来看看

deeply 2003-08-22
  • 打赏
  • 举报
回复
gz
eaglezhao 2003-08-22
  • 打赏
  • 举报
回复
Raptor(猛禽) 说的对,如果你不在DLL内部控制线程冲突,那么就换一种方法,不要使用DLl吧。
Erice 2003-08-22
  • 打赏
  • 举报
回复
dcom很难穿越防火墙一类的。用SOCKET虽然不安全,但稳定。
myling 2003-08-22
  • 打赏
  • 举报
回复
呵呵,

你的dll关闭的时候是不是释放了form的handle?
可能是你创建的时候没有……


把你的创建和释放form的代码贴出来看看
猛禽 2003-08-22
  • 打赏
  • 举报
回复
不是设置的问题,而是编程的时候你必须时刻想到,你在DLL里的每一个函数里的每一句代码都可能同时被执行,而在这种情况下,你的程序会不会有问题,如:全局变量,或DLL的函数参数是一个指针,此指针所指的对象是不是可能同时被其它线程访问,诸如此类的问题都应该避免,才能防止出现你说的问题
danny_ht204 2003-08-22
  • 打赏
  • 举报
回复
楼上的仁兄,不好意思
能不能说明白一点。
DLL线程安全是否需要经过什么样的设置。
猛禽 2003-08-22
  • 打赏
  • 举报
回复
你的DLL程序不是线程安全的

1,178

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 数据库及相关技术
社区管理员
  • 数据库及相关技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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