gpt4 book ai didi

Delphi如何使用typedef void *参数调用C++ dll函数?

转载 作者:行者123 更新时间:2023-12-03 15:30:38 24 4
gpt4 key购买 nike

我有一个用 C 编写的 dll。我的 delphi 包装器正在从 c++ dll 调用函数。

这是 C++ 代码:

typedef enum EFTDeviceControlAction
{
EFT_DCA_CR_CARD_RETRACT = 0x01,
EFT_DCA_CR_CARD_REPOSITION = 0x02,
EFT_DCA_CR_SHUTTER_OPEN = 0x03,
EFT_DCA_CR_SHUTTER_CLOSE = 0x04,
EFT_DCA_CR_CARD_EJECT = 0x05,
}

typedef enum EFT_PrintOptions {
poPrintState = 0,
poPrintFirst = 1,
poPrintSubsequent = 2,
poPrintFinal = 3,
poPrintAbort = 9
} EFT_PrintOptions;


typedef void * EFT_HANDLE;

int EFT_CreateSession(EFT_HANDLE * h);
int EFT_DestroySession(EFT_HANDLE h);
int EFT_ReadProperty(EFT_HANDLE h, int table, int index, char * pValue, unsigned int maxLength);
int EFT_WriteProperty(EFT_HANDLE h, int table, int index, char * pValue);
...

这是delphi代码:

EFTDeviceControlAction = (
EFT_DCA_CR_CARD_RETRACT = $01,
EFT_DCA_CR_CARD_REPOSITION = $02,
EFT_DCA_CR_SHUTTER_OPEN = $03,
EFT_DCA_CR_SHUTTER_CLOSE = $04,
EFT_DCA_CR_CARD_EJECT = $05,
);

EFT_PrintOptions = (
poPrintState = 0,
poPrintFirst = 1,
poPrintSubsequent = 2,
poPrintFinal = 3,
poPrintAbort = 9
);

EFT_HANDLE = pointer;

function EFT_CreateSession(var h: EFT_HANDLE): Integer; stdcall; external 'api.dll';
function EFT_DestroySession(h: EFT_HANDLE): Integer; stdcall; external 'api.dll';
function EFT_ReadProperty(h: EFT_HANDLE; table: Integer; index: Integer; pValue: PChar; maxLength: Cardinal): Integer; stdcall; external 'api.dll';
function EFT_WriteProperty(h: EFT_HANDLE; table: Integer; index: Integer; pValue: PChar): Integer; stdcall; external 'api.dll';

我遇到的问题是线路(C++)

typedef void * EFT_HANDLE 

这条线在Delphi中是如何定义的?这是一个指针,过程吗???当我调用函数时,我应该使用什么值作为参数?

对于每次调用,我都会在模块中的地址 0040537B 处遇到访问冲突

最佳答案

typedef void * EFT_HANDLE;

声明类型的名称是EFT_HANDLE,它是void*的别名。 void* 只是一个无类型指针。

所以,在 Delphi 中你可以这样定义它:

type
EFT_HANDLE = Pointer;

这正是您已经做过的。

你的其余翻译看起来基本上很合理。我有以下意见:

  1. 您确定调用约定是 stdcall 吗?您显示的 C++ 代码未指定调用约定,这总是意味着 cdecl
  2. 使用 PAnsiChar 而不是 PChar,这样您的代码在 Unicode Delphi 以及旧的非 Unicode Delphi 上都是正确的。

访问冲突的明显位置是以空字符结尾的字符串。查看调用 EFT_ReadProperty 的代码会很有帮助。它需要看起来像这样:

var
prop: AnsiString;
....
SetLength(prop, 128); // for example, not sure what value is needed here
retval := EFT_ReadProperty(handle, index, PAnsiChar(prop), Length(prop)+1);
// the +1 is for the null-terminator, but the library will specify exactly
// how that is handled and it could equally be that the +1 is omitted

关于Delphi如何使用typedef void *参数调用C++ dll函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20563386/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com