2010-12-04 3 views
1

Ich versuche, die folgenden C-Header in äquivalenten Delphi-Versionen zu konvertieren:einen Zeiger auf eine Funktion für einen C Rückruf in Delphi Providing

/** 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; 

Mein Delphi Code wie folgen im Moment aussieht:

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; 

Das Problem ist, dass ich ziemlich sicher bin, dass ich diese falsch behandle, da ich mich nicht erinnern kann, wie man einen Zeiger auf die zwei Funktionen erhält. Meine Frage ist: Wie kann ich einen Zeiger auf die malloc-Funktion erhalten, wenn ich versuche, sie zum Beispiel yajl_alloc_funcs.malloc zuzuordnen?

Alternativ, wenn ich etwas sehr falsch in meiner Übersetzung mache, was ist der "richtige" Ansatz hier?

Update: Es scheint einige Verwirrung darüber zu geben, was ich verlange. Ich habe tatsächlich Methode implementiert und ich versuche, sie auf die DLL zu liefern mit dem zuvor eingefügten Datensatz mit dem folgenden 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; 
.. 

Was mir einen Fehler gibt: E2009 Inkompatible Typen: ‚reguläres Verfahren und Verfahren Zeiger ' Was ich vermute, weil ich etwas falsch in meiner Header-Übersetzung getan habe.

Jede Hilfe würde sehr geschätzt werden.

+0

Konvertierung * von * C * zu * Delphi? Du schreibst die Logik besser um ... –

+0

@ ring0 - Ich bin mir nicht sicher, ob ich deinen Standpunkt sehe, wo ist das Logikproblem? – jamiei

+0

@ ring0 Sie haben die Frage nicht verstanden –

Antwort

0

Sie müssen nun die Funktionen malloc free und realloc definieren, die Sie an diese C-Bibliothek übergeben. Sie können sie in Delphi implementieren, indem Sie GetMem, FreeMem und ReallocMem aufrufen.

+0

Entschuldigung für die Verwirrung.Das Problem ist nicht mit der Implementierung der Funktionen, aber ich denke mit der Übersetzung der Header. – jamiei

+0

Mit diesem Code können Sie die Speicherzuweisung in der C-Bibliothek überschreiben. Wenn Sie dies tun möchten, müssen Sie malloc, free usw. liefern. Wenn Sie dies nicht tun möchten, können Sie dies wahrscheinlich ignorieren. Serg ist korrekt, Objekt ist ein Fehler, da es sich um freie Funktionen und nicht um Instanzmethoden handelt. –

+0

Dank David, ich weiß, wofür sie sind und habe die Implementierungen bereits woanders, aber ich habe Probleme mit den übersetzten Headern, wo ich denke, dass mein Problem ist. – jamiei

4

Verwenden Sie nicht "von Objekt" - es ist hier irrelevant.


Update: Welche Codezeile ein Fehler gibt? Ich kann es mir nicht vorstellen, der nächste Code kompiliert und funktioniert wie erwartet:

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; 
+0

Die Zeile, die die Funktion dem Datensatz zuweist. Ich bekomme einen inkompatiblen Typen, Kardinal und Zeiger Fehler. – jamiei