dll封装一个clientsocket后,如何实现onread事件 ( 积分: 100 )

  • 主题发起人 主题发起人 GsyyStudy
  • 开始时间 开始时间
我一般不上qq,
另外,忘了说明,我那个dll是在delphi2006下,基于indy10编译的,如果你不是用的indy10,那么请修改相应的数据类型即可。

主程序中的调用可以参看压缩包内的例子程序,有收发数据,广播数据的使用示例。
 
to ufo:谢谢你提供的帮助,那我改变相应的类型试试,我现在用的是delphi7。如果有啥问题,我在留言.
 
要不燃你可以dll + PBL 可以让你很爽啊! 在bpl 里面可以放任何VCL任何控件! 然后在DLL输出你想输出的东西. 就是在发布你的dll接口时多带几个VCL包. 你自己衡量吧
 
to ufo:按照你做的dll,我在delphi7中转换数据类型时,遇到一个问题,就是
steam如何转换成为string,急盼!!
to kk2000:你说的有些抽象,能不说的具体一点!
 
留个QQ吧! 我的43350195 估计我以后也要做类似的东西!
可以聊聊.
 
procedure TUDPMainForm.UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
DataStringStream: TStringStream;
s: String;
begin
DataStringStream := TStringStream.Create('');
try
DataStringStream.CopyFrom(AData, AData.Size);
Memo1.Lines.Add('Received "' + DataStringStream.DataString + '" from ' + ABinding.PeerIP + ' on port ' + IntToStr(ABinding.PeerPort));
s := 'Replied from ' + UDPServer.LocalName + ' to "' + DataStringStream.DataString + '"';
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));
finally
DataStringStream.Free;
end;
end;
 
上面给的是indy例子里面的,或者,也可以这样试试,代码随手写的,未经验证,思路大致如此。
var
s: string;
begin
setlength(s,AData.Size);
AData.Position:= 0;
AData.ReadBuffer(s[1],AData.Size);
end;
 
to indy:你给的将stream转化为string的代码很好,我测试通过了,我现在在改装dll了,如果dll中封装了触发自动接收的消息过程,你给了我很大的帮助呀,谢谢!!
 
to indy:我按你做的,想把接收消息的这个过程
procedure RC_send_message(var msg: TMessage)
封装到dll中,作了好长时间,就是不行,再次向你请教了!!!
 
to indy:我在dll中这样封装的:dll这样写的可以生成:
procedure RC_send_message(var msg: TMessage);stdcall;
var ss: string;
begin
ss:= pchar(msg.LParam);
case msg.WParam of
1000: ss:=ss;
1001: ss:=ss;
2000..2001:
begin
ss:=ss;
end;
end;
end;
我不知dll是否有问题,如何在主程序中调用,请指教!!
 
const
send_msg_id= WM_USER + 35671;
你在dll内的IdUDPServer1UDPRead事件内直接:
sendmessage(Host_handle,send_msg_id,0,integer(pchar(s)));
其中Host_handle是主程序传入的一个主窗口handle

然后在主程序内声明消息过程:
procedure RC_send_message(var msg: TMessage); message send_msg_id;

实现消息过程:
procedure TForm1.RC_send_message(var msg: TMessage);
begin
//显示收到的udp字符串
showmessage( pchar(msg.LParam));

end;

另外,也可以使用回调函数来实现这个过程,不过,个人感觉消息更简单一点。
 
to ufo:谢谢你给的在dll中封装消息的过程,我也测试了,完全可以。不过这个包含过程的dll如果通过delphi调用,可以非常简单的实现。但是如果让其他的语言来调用,就没有很好的移植性。你说可以通过对调函数来实现,麻烦你在给我讲讲如何用回调函数来实现,劳驾
你了,谢谢!热盼
 
pchar是通用数据类型,其他语言调用应该不存在问题。关键是有些涉及到导入导出的函数过程要加 stdcall;约定
回调函数的例子,论坛上很多,我就不重复了:
http://www.delphibbs.com/delphibbs/dispq.asp?LID=2034215
 
to ufo!我是这样申明回调函数的,就是不能编译,有错误,请你看看,我现在脑子都乱了
,前段时间我是看到了回调函数可以实现,虽然明白回调函数是咋回事,但对如何写回调函数以及如何调用总是一头雾水,很模糊,昨天我们软件开发部的负责人催促了,水平有限呀!最后一次请你结合本例,指导一下好吗?
type
Tpostmessage=Function(s:string;lpParam: LPARAM):pchar;stdcall; ////我定义回调函数postmessage
function post_message (Host_handle:string;const s: string;lpParam: LPARAM):pchar;stdcall;
begin

sendmessage(Host_handle,send_msg_id,flag,integer(pchar(s)));

end;
 
既然用了回调函数,就不需要使用消息了。
而且,不要在和dll以及其他语言打交道的时候使用 string类型,切记。
要使用回调函数,可按下面的步骤:
1。声明一个函数,并实现它。回调函数不能是类方法。
2。初始化dll时传入这个函数地址,并把它保存起来
3。dll内收到消息时调用这个函数。

再说,sendmessage消息方式只是在vcl的消息分发系统多绕了几下。其他也和回调函数一样的,没有本质区别。

结合你的例子,推荐用消息方式,更简单,更通用。
 
to ufo:谢谢!我试试看,如果解决了,我就散分了,再也不想为这个问题困扰了
 
to ufo:现在我通过delphi程序调用dll函数的返回值或参数可以实现消息的接收,可pb调用
不行,原因是定义的函数的返回值或参数的类型是pchar,因为在pb中不能识别pchar,但同时存在的矛盾是函数的返回值如果不是pchar,delphi调用就不行了。这个问题该如何解决呢?请你谈谈你的看法!
 
pchar其实就是一个指向某内存块的指针,该内存块以#0结尾。
pb我没有用过,但应该有操作内存的函数吧,最原始的方法,把这个pchar指向的内存拷贝到pb的字符串内,总可以的。
你或者可以查查pb的函数资料,看有没有操作#0结尾的字符串或者内存的,有的话,问题就简单了。
 
一,我想最好用COM实现你的CLIENTSOCKET
二,如果用于传送错误信息,我想最好在先定义个PAS文件,用于定义各种错误标识及错误信息,然后由DLL传回来的是那个标识,再用CLIENT去寻找那个标识所定义的内容.
 
ufo说的没错,我现在解决了pchar类型的问题,在pb中不能识别delphi的string类型。在delphi的dll中函数的参数和返回值不能定义为string而是要定义为pchar,pb调用delphi编译的dll时把dll中为pchar的定义为string就OK了。
 
后退
顶部