2010-01-13 85 views
1

我需要调用DLL文件在我的Delphi代码,这里是DLL头文件的代码片段:需要VC代码转换为德尔福

#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); 

我需要在我的德尔福调用DLL函数“UpdateBooks”码。 如何将这些代码转换为delphi?谢谢!

+0

什么是Delphi版本? – ThinkJet 2010-01-13 13:25:56

+0

什么是sizeof(_BookTime)和sizeof(_stBookData)?记录是打包还是与机器字边界对齐? – ThinkJet 2010-01-13 13:29:32

+0

狮子座,哪部分翻译是你遇到的麻烦?要求*这个特定的*代码被翻译,使得这个问题有可能被封闭为“太本地化”。一般的全球观众不关心如何翻译这个特定的代码。也许你想知道什么“结构”的意思,或什么德尔福类型“无符号字符”对应,或者什么宏,或什么效果所有这些“const”修饰符。问一个可能很容易应用于*其他* C++代码以及此代码的问题。 – 2010-01-13 16:43:12

回答

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 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; 

奖金:

// --- 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; 

共同德尔福风格调用函数相同的测试C型和帕斯卡风格的电话:-)

// --- 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; 
+0

参数“pBookdata”可能包含多个TBookData结构,“nBookDataCounter”指出TBookData结构的数目。 – Leo 2010-01-13 15:40:38

+0

狮子座,这不是*必然* ThinkJet的翻译问题,但它会使函数调用看起来有点奇怪。您将拥有一个数组,但您只需将第一个元素传递给该函数:'UpdateBooks(...,BookData [0],Length(BookData))'。 ThinkJet,最好是将C++中的指针参数转换为Delphi中的指针参数。 – 2010-01-13 16:38:27

+0

对齐记录?可能需要打包。另外我认为除了pbookdata之外,所有的CONST都会被删除,因为那个解除引用(*)被删除了。 – 2010-01-13 16:39:48

3

使用h2pas!虽然它是一个freepascal工具,但它应该生成与Delphi兼容的代码。