How can I extract data from Packed Record with external DLL using Delphi? -
i'm making delphi program using external dll. dll supports when request occurs sending window message client.
i defined packed record below:
type // message packet send dll trecv_packet = packed record nid: integer; lpdata: pointer; end; lprecv_packet = ^trecv_packet; // request record reqblock = packed record id: array [0..7] of char end; lpreqblock = ^reqblock; // response record resblock = packed record title: array[0..255] of char; _dt: char; description: array[0..1204] of char; _time: char; end; lpresblock = ^resblock; if send request, dll send window message client. found out explanation in document. dll sends recv_packet's memory address in message.lparam. result, want datas of resblock using message.lparam. code wrote send broken datas always. want pure data it. how can do?
receiving message procedure below:
procedure tform.onreceivedata(var message: tmessage); var recvpacket: lprecv_packet; _resblock: lpresblock; begin // actually, don't know why message.lparam parameter of lprecv_packet. how recvpacket := lprecv_packet(message.lparam); works? _resblock := lpresblock(recvpacket^.lpdata); showmessage(_resblock^.title); // broken datas... end; updated:
the original api definition below:
function etk_request(hwnd: hwnd; psztrcode: pansichar; lpdata: pointer; ndatasize: integer; bnext: boolean; pszcontinuekey: pansichar; ntimeout: integer): integer; stdcall; external api_dll; procedure onreceivedata(var message: tmessage); message wm_user + xm_receive_data;
we don't have documentation looking at. did find this online document (which not in english), this header file, , various online examples/translations vb, c#, , c++. based on those, delphi code should more this:
type // message packet send dll trecv_packet = packed record nrqid: integer; ndatalength: integer; ntotaldatabuffersize: integer; nelapsedtime: integer; ndatamode: integer; sztrcode: array[0..10] of ansichar; ccont: array[0..0] of ansichar; szcontkey: array[0..18] of ansichar; szuserdata: array[0..30] of ansichar; szblockname: array[0..16] of ansichar; lpdata: pbyte; end; lprecv_packet = ^trecv_packet; tmsg_packet = packed record nrqid: integer; nissystemerror: integer; szmsgcode: array[0..5] of ansichar; nmsglength: integer; lpszmessagedata: pbyte; end; lpmsg_packet = ^tmsg_packet; treal_recv_packet = packed record sztrcode: array[0..3] of ansichar; nkeylength: integer; szkeydata: array[0..32] of ansichar; szregkey: array[0..32] of ansichar; ndatalength: integer; pszdata: pansichar; end; lprecv_real_packet = ^trecv_real_packet; // following records not documented or defined (where did them?), // if above records indication, fields in these records // should using ansichar fields... // request record reqblock = packed record id: array [0..7] of ansichar; end; lpreqblock = ^reqblock; // response record resblock = packed record title: array[0..255] of ansichar; _dt: ansichar; description: array[0..1204] of ansichar; _time: ansichar; end; lpresblock = ^resblock; ... const xm_disconnect = 1; xm_receive_data = 3; xm_receive_real_data = 4; xm_login = 5; xm_logout = 6; xm_timeout_data = 7; const request_data = 1; message_data = 2; system_error_data = 3; release_data = 4; function etk_request(hparentwnd: hwnd; psztrcode: pansichar; lpdata: pointer; ndatasize: integer; bnext: bool; pszcontinuekey: pansichar; ntimeout: integer): integer; stdcall; external api_dll; procedure etk_releasemessagedata(lp: lparam); stdcall; external api_dll; procedure etk_releaserequestdata(nrequestid: integer); stdcall; external api_dll; type tform1 = class(tform) private procedure onreceivedata(var message: tmessage); message wm_user + xm_receive_data; ... end; procedure tform1.onreceivedata(var message: tmessage); var recvpacket: lprecv_packet; _resblock: lpresblock; msgpacket: lpmsg_packet; begin case message.wparam of request_data: begin recvpacket := lprecv_packet(message.lparam); // make sure recvpacket^.ndatalength >= sizeof(resblock) // before accessing data... _resblock := lpresblock(recvpacket^.lpdata); showmessage(_resblock^.title); end; message_data: begin msgpacket := lpmsg_packet(message.lparam); //... etk_releasemessagedata(message.lparam); end; system_error_data: begin msgpacket := lpmsg_packet(message.lparam); //... etk_releasemessagedata(message.lparam); end; release_data: begin //... etk_releaserequestdata(message.lparam); end; end; end;
Comments
Post a Comment