Delphi call a DLL
I have a DLL and want to call it from Delphi
extern "C" export_dll_function int RetScreen(int number, char** pbuffer, unsigned long* psize,
IMAGE_RESOLUTION resolution, float zoom, int dx, int dy);
[DllImport("API.DLL", EntryPoint = "_RetScreen")]
public static extern int pRetScreen(int number, ref byte[] pdata, ref long size, int res, float zoom, int d开发者_开发技巧x, int dy);
which delphi type refers to char** pbuffer for the prototype? (it is an image)
Taking my cue from the C# definition as well as the C version, it looks more like pbuffer is meant to be a pointer to a byte buffer. That is, in delphi it would be better as a PByte, passed by reference. No need to use a PChar when you really want a PByte.
eg.
type
IMAGE_RESOLUTION = integer; // judging from the c# parameters...
float = Single; // 4 bytes...
TRetScreenFn = function(number: integer;
var buffer: PByte;
var size: Cardinal;
resolution: IMAGE_RESOLUTION;
zoom: float;
dx : integer;
dy : integer): integer; cdecl;
(I'm assuming cdecl here from the extern "C" -- might be wrong here, depending on what "export_dll_function" means. If it's not this, it'll probably be stdcall instead.)
If it's possible for nil to be given instead of buffer or size, you won't be able to use "var". In that case, you'd need to do something like this:
type
PPByte = ^PByte;
PCardinal = ^Cardinal;
TRetScreenFn = function(number: integer;
buffer: PPByte;
size: PCardinal;
resolution: IMAGE_RESOLUTION;
zoom: float;
dx : integer;
dy : integer): integer; cdecl;
This is essentially the same thing. Except with the first version, the compiler will enforce the var parameters to be non-nil. This second version, it just sees pointers, and doesn't care.
Then, you know the rest (ignoring sane error checks):
var
retScreen : TRetScreenFn;
dll : HMODULE;
begin
dll := LoadLibrary("API.dll");
try
retScreen := TRetScreenFn(GetProcAddress(dll, "RetScreen"));
// ... call retScreen(); do stuff...
finally
CloseHandle(dll);
end;
end;
Jqno's close. A char** is an array of C-strings, but C doesn't do arrays or strings the way Delphi does. The base type here is a PAnsiChar, and you need an unbounded array. Declare it as a PCStringArray, defined like this:
type
TCStringArray = Array [0..0] of PAnsiChar;
PCStringArray = ^TCStringArray;
Number is most likely the number of the upper bound to your array. You declare it as [0..0]
, but the actual size is [0..number - 1]
.
It works ! Otherchirps, Rob Kennedy, mghie, Mason Wheeler, thank you very much !
For anyone else having the same problem: This is the correct function declaration (see otherchirps's post):
TRetScreenFn = function(number: integer; var buffer: PByte; var size: Cardinal; resolution: IMAGE_RESOLUTION; zoom: float; dx : integer; dy : integer): integer; stdcall;
(worked with stdcall)
type PByte = ^TByte; TByte = array of byte;
Called with these parameters: RetScreen(int, buffer: PByte, int, int, float, int, int). Function names inside dll for getting images based on those parameters are: GetImage and GetWindowImageQEx.
Rob Kennedy, I couldn't post more documentation because i don't have it. It's about Arecont's camera DLL (AV2000sdk.dll). Unfortunately, Arecont doesn't allow it's full SDK (for delphi and .net) to be downloaded.
Thanks again.
精彩评论