需要将VC代码转换为Delphi

时间:2010-01-13 11:41:10

标签: delphi dll visual-c++

我需要在我的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?谢谢!

3 个答案:

答案 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的文章和工具对我非常非常有帮助,特别是

Pitfalls of converting

Conversion Helper Package