Discussion:
OnUDPRead event handler...
(too old to reply)
Gene Buckle
2008-07-08 22:57:14 UTC
Permalink
I'm working on setting up a UDP server to run within a DLL and I'm having
a difficult time assinging the OnUDPRead handler.

Right now I'm working with just an empty handler:

procedure UDPReadHandler(AThread : TIdUDPListenerThread; AData : TIdBytes;
ABinding : TIdSocketHandle);
begin
end;

followed later by...

UDPServer := TIdUDPServer.Create(nil);
UDPServer.DefaultPort := 5502;
UDPServer.Active := true;
UDPServer.OnUDPRead := UDPReadHandler;

The UDPServer.OnUDPRead line generates:
"E2009 Incompatible types: 'method pointer and regular procedure'"

Is there any way I can get around this or do I have to create a class just
to handle this one function?

tnx!

g.
--
Proud owner of F-15C 80-0007
http://www.f15sim.com - The only one of its kind.
Remy Lebeau (TeamB)
2008-07-08 23:49:09 UTC
Permalink
This post might be inappropriate. Click to display it.
Gene Buckle
2008-07-09 14:03:49 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Gene Buckle
"E2009 Incompatible types: 'method pointer and regular procedure'"
Your event handler needs to be a method of a class, not a standalone
function.
That's what I suspected.
Post by Remy Lebeau (TeamB)
Post by Gene Buckle
Is there any way I can get around this or do I have to create a
class just to handle this one function?
Creating a class is the clean way to do it. There is a way to hack it by
TIdBytes; ABinding : TIdSocketHandle);
begin
//...
end;
var
M: TMethod;
begin
M.Data := UDPServer;
M.Code := UDPReadHandler;
UDPServer.OnUDPRead := TUDPReadEvent(M);
end;
Gambit
Ahh, many thanks for that! :)

g.
--
Proud owner of F-15C 80-0007
http://www.f15sim.com - The only one of its kind.
Gene Buckle
2008-07-09 14:07:32 UTC
Permalink
Post by Remy Lebeau (TeamB)
TIdBytes; ABinding : TIdSocketHandle);
begin
//...
end;
var
M: TMethod;
begin
M.Data := UDPServer;
M.Code := UDPReadHandler;
I get "Not enough actual parameters" with the M.Code assignment.

Ideas?

g.
--
Proud owner of F-15C 80-0007
http://www.f15sim.com - The only one of its kind.
rejj
2008-07-09 14:54:28 UTC
Permalink
Post by Gene Buckle
Post by Remy Lebeau (TeamB)
TIdBytes; ABinding : TIdSocketHandle);
begin
//...
end;
var
M: TMethod;
begin
M.Data := UDPServer;
M.Code := UDPReadHandler;
I get "Not enough actual parameters" with the M.Code assignment.
Ideas?
g.
I think you'd be better off using a an instantiated class or a class
with static procedures.

But "M.Code := @UDPReadHandler;" is the correction you're looking for.

However I'm unsure if M.Data := UDPServer; is the correct way to set
data, since my understanding is that the Data property is supposed to
hold the parameters that are sent to M.Code;


Easiest way to do it with imho:

Type
aSimpleStaticClass = class
private
Class procedure UDPReadHandler(AThread : TIdUDPListenerThread;
AData: TIdBytes; ABinding : TIdSocketHandle);
end;
Post by Gene Buckle
Post by Remy Lebeau (TeamB)
implementation
Class Procedure aSimpleStaticClass.UDPReadHandler(AThread:
TIdUDPListenerThread; AData: TIdBytes; ABinding: TIdSocketHandle);
Begin
//your code to handle reading;
end;



<< where you need to set up the UDPServer, no need to instantiate an
object of type aSimpleStaticClass since the procedure is a static one.
UDPServer.OnUDPRead := aSimpleStaticClass.UDPReadHandler;

My 2 cents.
Gene Buckle
2008-07-09 15:33:37 UTC
Permalink
Post by rejj
Post by Gene Buckle
Post by Remy Lebeau (TeamB)
TIdBytes; ABinding : TIdSocketHandle);
begin
//...
end;
var
M: TMethod;
begin
M.Data := UDPServer;
M.Code := UDPReadHandler;
I get "Not enough actual parameters" with the M.Code assignment.
Ideas?
g.
I think you'd be better off using a an instantiated class or a class
with static procedures.
However I'm unsure if M.Data := UDPServer; is the correct way to set
data, since my understanding is that the Data property is supposed to
hold the parameters that are sent to M.Code;
Thanks, I'll give that a shot.

g.
--
Proud owner of F-15C 80-0007
http://www.f15sim.com - The only one of its kind.
Remy Lebeau (TeamB)
2008-07-09 16:36:19 UTC
Permalink
Yes. My bad.
Post by rejj
However I'm unsure if M.Data := UDPServer; is the correct
way to set data
The M.Data member becomes the 'Self' pointer for the method call. As I
think more about it, I think you are right, though. Since the event handler
is not actually a class member, the parameters will use different CPU
registers than if it had been a class member. M.Data will be passed via
EAX, but the event handler will be expecting the AThread parameter to be in
EAX instead.
Post by rejj
my understanding is that the Data property is supposed
to hold the parameters that are sent to M.Code;
Only the 'Self' parameter. Not all of the parameters. There is no room for
them.
<snip>

Yes, that would work. But just to be clear, the only reason that works is
because 'class' methods still have a hidden 'Self' parameter. It just
points to the class's RTTI type rather than an object. If you had declared
the method as actually being 'static' as well, then it wouldn't work
anymore.


Gambit

Loading...