我需要在我的delphi代码中调用DLL文件,这里是DLL头文件的代码片段:
#define BookInfoDLL __declspec(dllexport)
struct _BookTime
{
unsigned char day;
unsigned char month;
unsigned short year;
};
struct _stBookData
{
unsigned char encrypt;
_BookTime bkTime;
unsigned int PageCount;
};
int BookInfoDLL UpdateBooks(const char * const pBookID,
const char cBookTypeWord,
const _stBookData * const pBookData,
const int nBookDataCounter);
我需要在我的delphi代码中调用dll函数“UpdateBooks”。 如何将这些代码转换为delphi?谢谢!
答案 0 :(得分:3)
使用h2pas!虽然它是一个freepascal工具,但它应该生成Delphi兼容代码。
答案 1 :(得分:2)
非托管Delphi代码的代码段(未经过测试,但根据评论中的建议进行编译和更改):
interface
type
TBookTime = packed record
day : byte; // unsigned 8-bit
month : byte;
year : word; // unsigned 16-bit
end;
TBookData = packed record
encrypt : byte;
bkTime : TBookTime;
PageCount : LongWord; // unsigned 32-bit
end;
TBookDataPtr = ^TBookData;
function UpdateBooks(
pBookID : PChar;
cBookTypeWord : byte;
pBookData : TBookDataPtr;
nBookDataCounter : integer
) : integer; stdcall; external 'dll_file_name.dll' name 'UpdateBooks';
implementation
// ...
end;
从delphi代码中简单调用UpdateBooks(...)
。
更新:代码已更改,感谢您发表评论!
以下是样本电话的摘要......
所有代码段的常用函数和常量:
// --- Test data fill utility and constants -----------------------------------
const
BOOK_ID = 'Test Book ID';
BOOK_TYPE_WORD = 'T';
BOOK_DATA_COUNT = 5;
procedure FillTestBookData(pBookData : TBookDataPtr; iTestNum : integer);
begin
if(pBookData = nil) then exit;
pBookData^.encrypt := iTestNum;
pBookData^.bkTime.day := iTestNum;
pBookData^.bkTime.month := iTestNum;
pBookData^.bkTime.year := 2000 + iTestNum;
pBookData^.PageCount := iTestNum;
end;
以普通Delphi风格调用函数:
// --- Test procedure in Delphi style -----------------------------------------
procedure TestBookUpdate_DelphiStyle;
var
bookArray : array of TBookData;
iBookNumber : integer;
begin
SetLength(bookArray, BOOK_DATA_COUNT);
try
for iBookNumber := Low(bookArray) to High(bookArray) do begin
FillTestBookData( @(bookArray[iBookNumber]), iBookNumber );
end;
UpdateBooks(
PChar(BOOK_ID), ord(BOOK_TYPE_WORD),
@(bookArray[Low(bookArray)]), BOOK_DATA_COUNT
);
finally
SetLength(bookArray, 0); // no explicit requirement to include in code
end;
end;
奖励:C风格和Pascal风格的相同测试调用: - )
// --- Test procedure in Old Delphi (plain Pascal) style ----------------------
type
TBookDataOldArray = array[0..0] of TBookData;
TBookDataOldArrayPtr = ^TBookDataOldArray;
// Store range checking compiler option state
{$IFOPT R+}
{$DEFINE RANGE_CHECK_ON}
{$ENDIF}
procedure TestBookUpdate_OldDelphiStyle;
var
bookArrayPtr : TBookDataOldArrayPtr;
iBookNumber : integer;
begin
GetMem(bookArrayPtr, BOOK_DATA_COUNT*sizeof(TBookData));
try
// Disable range checking compiler option
{$R-}
for iBookNumber := 0 to BOOK_DATA_COUNT - 1 do begin
FillTestBookData(@(bookArrayPtr^[iBookNumber]), iBookNumber);
end;
// Restore range checking compiler option if turned on before disabling
{$IFDEF RANGE_CHECK_ON}{$R+}{$ENDIF}
UpdateBooks(
PChar(BOOK_ID), ord(BOOK_TYPE_WORD), TBookDataPtr(bookArrayPtr), BOOK_DATA_COUNT
);
finally
FreeMem(bookArrayPtr);
end;
end;
// --- Test procedure in C style ---------------------------------------------
procedure TestBookUpdate_CStyle;
var
bookArrayPtr : TBookDataPtr;
curBookPtr : TBookDataPtr;
curBookNumber : integer;
begin
bookArrayPtr := AllocMem( BOOK_DATA_COUNT * sizeof(TBookData) );
try
curBookNumber := 0;
curBookPtr := bookArrayPtr;
while(curBookNumber < BOOK_DATA_COUNT) do begin
FillTestBookData( curBookPtr, curBookNumber );
inc(curBookNumber);
inc(curBookPtr, 1);
// Another pointer increment solution is :
// curBookPtr := PChar(curBookPtr) + sizeof(TBookData);
end;
UpdateBooks( PChar(BOOK_ID), ord(BOOK_TYPE_WORD), bookArrayPtr, BOOK_DATA_COUNT );
finally
FreeMem(bookArrayPtr);
end;
end;
答案 2 :(得分:1)
我昨天结束了第一次C头转换。 TeamB成员Rudy Velthuis的文章和工具对我非常非常有帮助,特别是