Delphi DLL - TClientSocket 事件

发布于 2024-09-08 01:00:12 字数 522 浏览 7 评论 0原文

我有一个带有 TClientSocket 组件的 DLL,它用于与电话系统机器通信。该 DLL 在导出方法中仅具有 PChar 参数,并且不使用包。

当我使用 Delphi 应用程序加载 DLL 时,所有事件都工作正常,到目前为止没有问题。

我的客户正在从控制台 Win32 Cobol 程序调用此 DLL,并且 TClientSocket 在事件发生时不会触发事件,它使用主循环调用 DLL 中的检查方法来了解是否有从电话系统返回的内容,如果它返回 OK 然后调用 Get 方法,这就是问题发生的地方:

在 TClientSocket.OnRead 事件中,我调用 TClientSocket.Socket.ReceiveText,并且服务器应用程序有几次返回,这让我认为该事件只是当我从 DLL 调用方法并且 TClientSocket 在缓冲区中保存多个返回时触发。

问题是我找不到任何分隔符来分割这个返回值。

我该如何解决这个问题?是否可以向 DLL 添加任何内容,以确保每次不从 Delphi 程序调用 OnRead 事件时都会触发该事件?

I have a DLL with a TClientSocket component, it is used to talk to a Telephone System Machine. The DLL only have PChar parameters in the exports methods, and is not using packages.

When I load the DLL with Delphi app, all the events works fine, no problem so far.

My customer is calling this DLL from a console Win32 Cobol program, and the TClientSocket do not trigger the events when its happen, it uses a main loop to call a check method in DLL to known if is there any returning from the Telephone system, if it returns OK then it call the Get Method, and here is where the problem happen:

In TClientSocket.OnRead event, I call TClientSocket.Socket.ReceiveText, and there are several returns from server app, what make me think that the event is only triggered when I call a method from DLL, and the TClientSocket is holding several returns in the buffer.

The problem is that I cant find any Delimiter to split this Return.

How can I fix this? Is there anything I can add to my DLL to make sure that the OnRead event will be triggered every time when it is not called from a Delphi Program?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

感悟人生的甜 2024-09-15 01:00:12

你可能需要在你的 dll 中有一个消息循环..(控制台应用程序缺少消息泵..)。所以在你的 dll 构造函数中实现类似的东西:

var Msg : TMsg;
     res : Integer;

.

While true Do Begin
        res := Integer( GetMessage(Msg, 0, 0, 0 ));
        If res = -1 Then
          Exit  // error
        else if res = 0 then
          exit  // WM_QUIT received
        else begin
          TranslateMessage( Msg );
          DispatchMessage( Msg );
        end;
End; { While }

看看类似的线程
http://www.mofeel.net/1102- comp-lang-pascal-delphi-misc/2763.aspx

you probably need a message loop in your dll .. (Console applications lack a message pump ..). SO implement something like this in your dll constructor:

var Msg : TMsg;
     res : Integer;

.
.
.

While true Do Begin
        res := Integer( GetMessage(Msg, 0, 0, 0 ));
        If res = -1 Then
          Exit  // error
        else if res = 0 then
          exit  // WM_QUIT received
        else begin
          TranslateMessage( Msg );
          DispatchMessage( Msg );
        end;
End; { While }

Take a look at a similar thread
http://www.mofeel.net/1102-comp-lang-pascal-delphi-misc/2763.aspx

ぶ宁プ宁ぶ 2024-09-15 01:00:12

最近,我遇到了和你类似的问题,我的 dll 中的 clientsocket 可以与 delphi-exe 一起使用,但不能与 c-console exe 一起使用,我记得 tclientsocket 正在使用选择事件模式,这需要主线程来处理消息循环,因此,

如果您在 dll 中使用非阻塞模式的 tclientsocket,主机不应该阻塞主线程,并且必须执行消息循环(例如,在控制台中调用时)程序)。

有时我们无法修改主机代码(我遇到的情况),那么我们可以这样做,

socket.sendtext();
repeat s :=socket.recevtext; 
until timeout or length(s)>0; 

当然你需要检查 s 是否是完整的数据包等等。

recently , i encountered a similar problem as you , my clientsocket in dll works ok with delphi-exe, but not with c-console exe , and i remembered tclientsocket is using select-event mode, which needs the main-thread to process the message loop, so ,

if your are using a tclientsocket with nonblock mode in a dll, the host should NEVER block the main-thread, and must do the message-loop (for ex, when calling in a console program).

sometimes we can not modify the host code (the case i meet), then we can do like this

socket.sendtext();
repeat s :=socket.recevtext; 
until timeout or length(s)>0; 

of course you need to check if s is the complete packet or so.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文