首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi如何使用typedef *参数调用c++ dll函数?

Delphi如何使用typedef *参数调用c++ dll函数?
EN

Stack Overflow用户
提问于 2013-12-13 09:47:40
回答 1查看 2K关注 0票数 4

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

这是C++代码:

代码语言:javascript
复制
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代码:

代码语言:javascript
复制
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++)

代码语言:javascript
复制
typedef void * EFT_HANDLE 

这一行是如何在Delphi中定义的?这是指针吗,过程?在调用函数时,参数的值是多少?

对于每一次呼叫,我在模块中的地址0040537B处都有访问冲突。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-13 09:48:30

代码语言:javascript
复制
typedef void * EFT_HANDLE;

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

因此,在Delphi中,您可以这样定义它:

代码语言:javascript
复制
type
  EFT_HANDLE = Pointer;

这正是你已经做过的。

其余的翻译看上去基本上是相当合理的。我有以下评论:

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

访问冲突的明显位置是以空结尾的字符串。查看您拥有的调用EFT_ReadProperty的代码将是有帮助的。它需要如下所示:

代码语言:javascript
复制
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
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20563386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档