加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi如何用typedef void *参数调用c dll函数?

发布时间:2020-12-15 09:15:11 所属栏目:大数据 来源:网络整理
导读:我有一个用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
我有一个用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,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,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;

这正是你已经做过的.

其余的翻译看起来基本上都很合理.我有这些评论:

>你确定调用约定是stdcall吗?您显示的C代码没有指定调用约定,这总是意味着cdecl.
>使用PAnsiChar而不是PChar,以便您的代码在Unicode Delphi以及旧的非Unicode Delphi上正确.

访问冲突的明显位置是以null结尾的字符串.查看调用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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读