I have to access a DLL with Delphi, but have only the .h file. Most functions are translated and work flawless, but not this part:
FUNCTION_PRE64 ULONG FUNCTION_PRE OpenModuleEx
(
ULONG moduleID,
ULONG nr,
unsigned char *exbuffer,
ULONG open_options
);
typedef struct
{
unsigned char address[256];
ULONG timeout;
ULONG portno;
ULONG encryption_type;
unsigned char encryption_password[32];
} DAPI_OPENMODULEEX_STRUCT;
My translation to Delphi is:
function OpenModuleEx
(
moduleID:Longint;
nr:Longint;
&buffer: exbuffer;
open_options: longint
): Longint; stdcall; external 'master.dll'
type exbuffer = packed record
address : array of byte;
timeout : Longint;
portno : Longint;
encryption_type : Longint;
encryption_password : Array of byte;
end;
I fill the record and call the function:
BinarySize := (Length('10.241.0.147') 1) * SizeOf(Char);
SetLength(buffer.address, BinarySize);
Move('10.241.0.147'[1], buffer.address[0], BinarySize);
buffer.portno := 9912;
buffer.timeout := 5000;
buffer.encryption_type := 0;
BinarySize := (Length('') 1) * SizeOf(Char);
SetLength(buffer.encryption_password, BinarySize);
Move(''[1], buffer.encryption_password[0], BinarySize);
lhandle := OpenModuleEx(42, 0, &buffer, 0 );
...but the returned handle is always 0
.
I'm no C expert and also no Delphi expert. My Delphi version is XE7. Who can help me to translate the struct to Delphi and how to fill it?
CodePudding user response:
The Delphi record translation is incorrect. It should be:
type
exbuffer = record
address : Array [0..255] byte;
timeout : Cardinal;
portno : Cardinal;
encryption_type : Cardinal;
encryption_password : Array [0..31] byte;
end;
The record should not be packed. ULONG
maps to an unsigned 32 bit type. And the arrays must be fixed length arrays.
The function declaration is wrong too. It should be:
function OpenModuleEx(
moduleID: Cardinal;
nr: Cardinal;
exbuffer: PByte;
open_options: Cardinal
): Cardinal; stdcall; external 'master.dll';
It also may be that the function should be cdecl
rather than stdcall
, we cannot tell.
CodePudding user response:
Your type for ULONG is incorrect. You either should be using Cardinal or more likely NativeUInt, which varies based on the choice of 32/64bit compilation. NativeUInt is used often in pointer addressing, and a lot of Delphi to Windows communication. It is the base datatype for THandle, HWND, UIntPtr, and others!
ULONG and Cardinal range 0 to 4 billion LongInt is -2 billion to 2 billion NativeUInt is 0 to 4 billion for 32bit or 0 to 1.8x10^19 in 64bit if I remember correctly
Andreas is correct about the need for 256 and 32 byte static arrays - and they likely must have a /0 termination character to indicate the end of the character string.
Adding as a comment would be so much easier than an "Answer"...but w/e...