为 Delphi 中的 C 回调提供函数指针

发布于 2024-10-06 04:59:28 字数 2088 浏览 2 评论 0原文

我正在尝试将以下 C 标头转换为等效的 Delphi 版本:

/** pointer to a malloc function, supporting client overriding memory
 *  allocation routines */
typedef void * (*yajl_malloc_func)(void *ctx, unsigned int sz);

/** pointer to a free function, supporting client overriding memory
 *  allocation routines */
typedef void (*yajl_free_func)(void *ctx, void * ptr);

/** pointer to a realloc function which can resize an allocation. */
typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, unsigned int sz);

typedef struct
    {
        /** pointer to a function that can allocate uninitialized memory */
        yajl_malloc_func malloc;
        /** pointer to a function that can resize memory allocations */
        yajl_realloc_func realloc;
        /** pointer to a function that can free memory allocated using
         *  reallocFunction or mallocFunction */
        yajl_free_func free;
        /** a context pointer that will be passed to above allocation routines */
        void * ctx;
    } yajl_alloc_funcs;

我的 Delphi 代码目前看起来像这样:

  Tyajl_malloc_func = function(context: pointer; sizeOf: Cardinal): Pointer of Object; cdecl;

  Tyajl_free_func = procedure(context: pointer; ptr: Pointer) of Object; cdecl;

  Tyajl_realloc_func = function(context: pointer; ptr: Pointer; sizeOf: cardinal): Pointer of Object; cdecl;
  yajl_alloc_funcs = record
    malloc: Tyajl_malloc_func;
    free: Tyajl_free_func;
    realloc: Tyajl_realloc_func;
    ctx: pointer;
  end;

问题是我很确定我错误地处理了这些,因为我不记得如何获取指向两个函数的指针。我的问题是:例如,当我尝试将其分配给 yajl_alloc_funcs.malloc 时,如何获取指向 malloc 函数的指针?

或者,如果我在翻译中做了一些非常错误的事情,那么这里的“正确”方法是什么?

更新:我的要求似乎有些混乱。我已经实现了实际的方法,并尝试使用前面粘贴的记录使用以下代码将它们提供给 DLL:

var
   alloc_funcs: yajl_alloc_funcs;
begin
   FillChar(alloc_funcs, SizeOf(alloc_funcs), #0);
   alloc_funcs.malloc := yajl_malloc;
   alloc_funcs.free := yajl_free;
   alloc_funcs.realloc := yajl_realloc;
..

这给了我一个错误: E2009 不兼容类型:“常规过程和方法指针” 我怀疑这是因为我在标题翻译中做错了一些事情。

任何帮助将不胜感激。

I'm trying to convert the following C headers to equivalent Delphi versions:

/** pointer to a malloc function, supporting client overriding memory
 *  allocation routines */
typedef void * (*yajl_malloc_func)(void *ctx, unsigned int sz);

/** pointer to a free function, supporting client overriding memory
 *  allocation routines */
typedef void (*yajl_free_func)(void *ctx, void * ptr);

/** pointer to a realloc function which can resize an allocation. */
typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, unsigned int sz);

typedef struct
    {
        /** pointer to a function that can allocate uninitialized memory */
        yajl_malloc_func malloc;
        /** pointer to a function that can resize memory allocations */
        yajl_realloc_func realloc;
        /** pointer to a function that can free memory allocated using
         *  reallocFunction or mallocFunction */
        yajl_free_func free;
        /** a context pointer that will be passed to above allocation routines */
        void * ctx;
    } yajl_alloc_funcs;

My Delphi code looks like this at the moment:

  Tyajl_malloc_func = function(context: pointer; sizeOf: Cardinal): Pointer of Object; cdecl;

  Tyajl_free_func = procedure(context: pointer; ptr: Pointer) of Object; cdecl;

  Tyajl_realloc_func = function(context: pointer; ptr: Pointer; sizeOf: cardinal): Pointer of Object; cdecl;
  yajl_alloc_funcs = record
    malloc: Tyajl_malloc_func;
    free: Tyajl_free_func;
    realloc: Tyajl_realloc_func;
    ctx: pointer;
  end;

The problem is that I'm pretty sure I'm treating these incorrectly as I'm unable to remember how to obtain a Pointer to the two functions. My question is: How can I obtain a pointer to the malloc function when I try to assign it to the yajl_alloc_funcs.malloc for example?

Alternatively, if I'm doing something very wrong in my translation, what is the "proper" approach here?

Update: There appears to be some confusion over what I'm asking. I have implemented actual methods and am trying to supply them to the DLL using the afore-pasted record using the following code:

var
   alloc_funcs: yajl_alloc_funcs;
begin
   FillChar(alloc_funcs, SizeOf(alloc_funcs), #0);
   alloc_funcs.malloc := yajl_malloc;
   alloc_funcs.free := yajl_free;
   alloc_funcs.realloc := yajl_realloc;
..

Which gives me an error of:
E2009 Incompatible types: 'regular procedure and method pointer'
Which I suspect to be because I've done something wrong in my header translation.

Any help would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怼怹恏 2024-10-13 04:59:28

不要使用“of Object”——它在这里无关紧要。


更新:哪一行代码给您带来了错误?我无法想象,下一个代码将按预期编译并工作:

type
  Tyajl_malloc_func = function(context: pointer; sizeOf: Cardinal): Pointer; cdecl;
  Tyajl_free_func = procedure(context: pointer; ptr: Pointer); cdecl;
  Tyajl_realloc_func = function(context: pointer; ptr: Pointer; sizeOf: cardinal): Pointer; cdecl;

  Tyajl_alloc_funcs = record
    malloc: Tyajl_malloc_func;
    free: Tyajl_free_func;
    realloc: Tyajl_realloc_func;
    ctx: pointer;
  end;

function yajl_malloc_func(context: pointer; sizeOf: Cardinal): Pointer; cdecl;
begin
  Result:= Pointer($1234);
end;

var
  yajl_alloc_funcs: Tyajl_alloc_funcs;


procedure TForm1.Button1Click(Sender: TObject);
begin
  yajl_alloc_funcs.malloc:= yajl_malloc_func;
  ShowMessage(Format('%p', [yajl_alloc_funcs.malloc(nil, 0)]));
end;

Don't use "of Object" - it is irrelevant here.


Update: Which line of code gives you an error? I can't imagine it, the next code compiles and works as expected:

type
  Tyajl_malloc_func = function(context: pointer; sizeOf: Cardinal): Pointer; cdecl;
  Tyajl_free_func = procedure(context: pointer; ptr: Pointer); cdecl;
  Tyajl_realloc_func = function(context: pointer; ptr: Pointer; sizeOf: cardinal): Pointer; cdecl;

  Tyajl_alloc_funcs = record
    malloc: Tyajl_malloc_func;
    free: Tyajl_free_func;
    realloc: Tyajl_realloc_func;
    ctx: pointer;
  end;

function yajl_malloc_func(context: pointer; sizeOf: Cardinal): Pointer; cdecl;
begin
  Result:= Pointer($1234);
end;

var
  yajl_alloc_funcs: Tyajl_alloc_funcs;


procedure TForm1.Button1Click(Sender: TObject);
begin
  yajl_alloc_funcs.malloc:= yajl_malloc_func;
  ShowMessage(Format('%p', [yajl_alloc_funcs.malloc(nil, 0)]));
end;
眼眸 2024-10-13 04:59:28

现在,您需要定义名为 malloc free 和 realloc 的函数,并将其传递给此 C 库。您可以在 Delphi 中通过调用 GetMem、FreeMem 和 ReallocMem 来实现它们。

You now need to define functions called malloc free and realloc which you pass to this C library. You can implement them in Delphi by calling GetMem, FreeMem and ReallocMem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文