简体   繁体   中英

Providing a pointer to a function for a C callback in Delphi

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.

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;

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM