Delphi上的C dll头文件

时间:2012-08-06 03:55:41

标签: c delphi dll

我想从“x.dll”加载一个函数,我有这个函数的定义(.h文件):

uint32 BioAPI_ModuleAttach(
    const BioAPI_UUID *ModuleGuid,
    const BioAPI_VERSION *Version,
    const BioAPI_MEMORY_FUNCS *MemoryFuncs,
    uint32 DeviceID,
    uint32 Reserved1,
    uint32 Reserved2,
    uint32 Reserved3,
    BioAPI_FUNC_NAME_ADDR *FunctionTable,
    uint32 NumFunctionTable,
    const void *Reserved4,
    BioAPI_HANDLE_PTR NewModuleHandle);

typedef uint32 BioAPI_HANDLE, *BioAPI_HANDLE_PTR;

但是,我只传递最后一个参数和其他我要传递的其他参数0(null)...我该如何实现?有没有办法用de .lib做自动?

我试过,但是我以错误的方式实施了......:\

function BioAPI_ModuleAttach(
           ModuleGuid: array of Byte; 
           Version: HWND; 
           MemoryFuncs: HWND; 
           DeviceID: UInt32; 
           Reserved1: UInt32; 
           Reserved2: UInt32; 
           Reserved3: UInt32; 
           FunctionTable: HWND; 
           NumFunctionTable: UInt32; 
           Reserved4: Pointer; 
           NewModuleHandle: PINT) : UInt32; cdecl; external 'PvFw.dll';

谢谢,关注。

3 个答案:

答案 0 :(得分:2)

我认为这可行:

function BioAPI_ModuleAttach(
  ModuleGuid: PByte; // pass a pointer to the first array element
  Version: PByte;    // PByte probably is wrong here, look up the type!
  MemoryFuncs: PByte; // Also probably wrong, what is BioAPI_MEMORY_FUNCS?
  DeviceID: UInt32; 
  Reserved1: UInt32; 
  Reserved2: UInt32; 
  Reserved3: UInt32; 
  FunctionTable: PBYTE; // pass a pointer to a BioAPI_FUNC_NAME_ADDR 
  NumFunctionTable: UInt32; // that's probably the length of the above
  Reserved4: Pointer; 
  NewModuleHandle: PUINT32) : UInt32; cdecl; external 'PvFw.dll';

如果所有参数都可以为零或NULL,则调用它应该有效:

var
  DeviceId: UInt32; // LongWord
  Handle: UInt32; // LongWord;
begin
  DeviceId := <something>
  Handle := 0;
  Res := BioAPI_ModuleAttach(nil, nil, nil, DeviceId, 0, 0, 0, nil, 0, nil, @Handle);

当然,这假设很多,因为您没有提供有关许多指针参数的任何信息。我已将它们宣布为PByte,但这可能是错误的。

答案 1 :(得分:2)

看看来源,我会像这样转换:

const
  BioAPI_MAX_STR_LEN = 255;

type
  BioAPI_RETURN = UInt32;

  BioAPI_VERSION_PTR = ^BioAPI_VERSION;
  BioAPI_VERSION = record
    Major: UInt32;
    Minor: UInt32;
  end;

  BioAPI_MALLOC = function(
    Size: UInt32;
    AllocRef: Pointer;
    FileName: PAnsiChar;
    Line: UInt32; 
  ): Pointer stdcall;

  // etc...

  BioAPI_MEMORY_FUNCS_PTR = ^BioAPI_MEMORY_FUNCS;
  BioAPI_MEMORY_FUNCS = record
    Malloc_func: BioAPI_MALLOC;
    Free_func: BioAPI_FREE;
    Realloc_func: BioAPI_REALLOC;
    Calloc_func: BioAPI_CALLOC;
    AllocRef: Pointer;
  end;

  BioAPI_FUNC_NAME_ADDR_PTR = ^BioAPI_FUNC_NAME_ADDR;
  BioAPI_FUNC_NAME_ADDR = record
    Name: array[0..BioAPI_MAX_STR_LEN - 1] of AnsiChar;
    Address: BioAPI_PROC_ADDR;
  end;

  // etc... I'll leave the rest for you. ;-)

function BioAPI_ModuleAttach(
  ModuleGuid: PGUID;
  Version: BioAPI_VERSION_PTR;
  MemoryFuncs: BioAPI_MEMORY_FUNCS_PTR;
  DeviceID,
  Reserved1,
  Reserved2,
  Reserved3: UInt32;
  FunctionTable: BioAPI_FUNC_NAME_ADDR_PTR;
  NumFunctionTable: UInt32;
  Reserved4: Pointer;
  var NewModuleHandle: HMODULE): BioAPI_RETURN; stdcall;  

请注意,在Win32中,BioAPI #defined为__stdcall,因此cdecl肯定是错误的。没有任何迹象表明必须打包记录。我会让他们保持自然对齐。

答案 2 :(得分:1)

const
  BioAPI_MAX_STR_LEN = 255;
  BioAPI_OK = 0;
  BioAPI_INVALID_HANDLE = 0;

type
  BioAPI_UUID = packed array[0..15] of Byte; // or TGUID
  BioAPI_UUID_PTR = ^BioAPI_UUID;

  BioAPI_DEVICE_ID = UInt32;

  BioAPI_VERSION = record
        Major: UInt32;
        Minor: UInt32;
  end;
  BioAPI_VERSION_PTR = ^BioAPI_VERSION;

    BioAPI_MALLOC = function(Size: UInt32; Allocref: Pointer): Pointer; cdecl;
  BioAPI_FREE = procedure(Memblock: Pointer; Allocref: Pointer); cdecl;
    BioAPI_REALLOC = function(Memblock: Pointer; Size: UInt32; Allocref: Pointer): Pointer; cdecl;
    BioAPI_CALLOC = function(Num: UInt32; Size: UInt32; Allocref: Pointer): Pointer; cdecl;

  BioAPI_MEMORY_FUNCS = record
        Malloc_func: BioAPI_MALLOC;
    Free_func: BioAPI_FREE;
        Realloc_func: BioAPI_REALLOC;
        Calloc_func: BioAPI_CALLOC;
        AllocRef: Pointer;
  end;
  BioAPI_MEMORY_FUNCS_PTR = ^BioAPI_MEMORY_FUNCS;

  BioAPI_PROC_ADDR = function: UInt32; stdcall;

  BioAPI_FUNC_NAME_ = record
        Name: packed array[0..BioAPI_MAX_STR_LEN-1] of AnsiChar;
        Address: BioAPI_PROC_ADDR;
  end;
  BioAPI_FUNC_NAME_ADDR = array[0..0] of BioAPI_FUNC_NAME_;
  BioAPI_FUNC_NAME_ADDR_PTR = ^BioAPI_FUNC_NAME_ADDR;

  BioAPI_HANDLE = UInt32;
  BioAPI_HANDLE_PTR = ^BioAPI_HANDLE;

function BioAPI_ModuleAttach(
    ModuleGuid: BioAPI_UUID_PTR;
    Version: BioAPI_VERSION_PTR;
    MemoryFuncs: BioAPI_MEMORY_FUNCS_PTR;
    DeviceID: BioAPI_DEVICE_ID;
    Reserved1: UInt32;
    Reserved2: UInt32;
    Reserved3: UInt32;
    FunctionTable: BioAPI_FUNC_NAME_ADDR_PTR;
    NumFunctionTable: UInt32;
    Reserved4: Pointer;
    var NewModuleHandle: BioAPI_HANDLE): UInt32; cdecl; external 'PvFw.dll';

procedure Test;
var
  NewModuleHandle: BioAPI_HANDLE;
begin
  if BioAPI_ModuleAttach(nil, nil, nil, 0, 0, 0, 0, nil, 0, nil, NewModuleHandle) = BioAPI_OK then
  begin
    if NewModuleHandle <> BioAPI_INVALID_HANDLE then
    begin
      // Success
    end;
  end;
end;

如果 cdecl 不是正确的约定替换 stdcall