Delphi调用DLL

时间:2009-11-25 13:02:19

标签: delphi api dll

我有一个DLL,想从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 dx, int dy);

哪个delphi类型引用char ** pbuffer作为原型? (这是一张图片)

3 个答案:

答案 0 :(得分:2)

从C#定义以及C版本中获取提示,看起来更像pbuffer是指向字节缓冲区的指针。也就是说,在delphi中,作为PByte会更好,通过引用传递。当你真的想要一个PByte时,不需要使用PChar。

例如

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; 

(我在这里假设来自extern“C”的cdecl - 在这里可能是错的,这取决于“export_dll_function”的含义。如果不是这样,那么它可能会改为stdcall。)

如果可以给出nil而不是缓冲区或大小,则无法使用“var”。在这种情况下,你需要做这样的事情:

type 
  PPByte = ^PByte;
  PCardinal = ^Cardinal;

  TRetScreenFn = function(number: integer;
                          buffer: PPByte;
                          size: PCardinal;  
                          resolution: IMAGE_RESOLUTION;
                          zoom: float;
                          dx : integer;
                          dy : integer): integer; cdecl; 

这基本上是一回事。除第一个版本外,编译器将强制var参数为非零。第二个版本,它只是看到了指针,并不关心。

然后,你知道其余的(忽略理智的错误检查):

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;

答案 1 :(得分:1)

Jqno很接近。 char **是一个C字符串数组,但C不像Delphi那样处理数组或字符串。这里的基类型是PAnsiChar,你需要一个无界数组。将其声明为PCStringArray,定义如下:

type
  TCStringArray = Array [0..0] of PAnsiChar;
  PCStringArray = ^TCStringArray;

数字很可能是数组上限的数字。您将其声明为[0..0],但实际尺寸为[0..number - 1]

答案 2 :(得分:0)

有效! Otherchirps,Rob Kennedy,mghie,Mason Wheeler,非常感谢你!

对于遇到同样问题的其他人: 这是正确的函数声明(参见otherchirps的帖子):

TRetScreenFn = function(number: integer;
                          var buffer: PByte;
                          var size: Cardinal;  
                          resolution: IMAGE_RESOLUTION;
                          zoom: float;
                          dx : integer;
                          dy : integer): integer; stdcall;

(与stdcall合作)

type
  PByte = ^TByte;
  TByte = array of byte;

使用以下参数调用: RetScreen(int,buffer:PByte,int,int,float,int,int)。 dll中用于根据这些参数获取图像的函数名称为: GetImage和GetWindowImageQEx。

Rob Kennedy,我无法发布更多文档,因为我没有。 这是关于Arecont的相机DLL(AV2000sdk.dll)。不幸的是,Arecont不允许下载完整的SDK(用于delphi和.net)。

再次感谢。