2017-02-10 18 views
1

我試圖在結構化數據類型中使用過程作爲在FreePascal中使用GTK + 3作爲其工具包的程序的回調函數。在結構化數據類型中使用過程作爲C庫的回調(GTK + 3)

在下面的例子(我是由gir2pascal工具(http://wiki.freepascal.org/gir2pascal)產生的GTK + 3綁定),我用先進的記錄,但我肯定會考慮的類或對象,如果它工作更好的/在所有這些問題。

發生的問題是,當調用回調過程時,它無法訪問其自己記錄中的任何其他內容。它似乎「忘記」它來自哪裏。

例如,在下面的例子中,我有整數myRecord.myInt,我可以通過調用過程myRecord.testProcedure來愉快地設置和檢索。然而,當testProcedure作爲一個C回調(當我點擊的按鈕),我會收到一些號碼(如30976),而不是7

{$MODESWITCH ADVANCEDRECORDS} 
uses gobject2, gtk3, math; 

type 
    myRecord=record 
    public 
     myInt: Integer; 
     procedure testProcedure; cdecl; 
    end; 

    procedure myRecord.testProcedure; cdecl; 
    begin 
    WriteLn(myInt); 
    end; 

var 
    recordInstance: myRecord; 
    button, win: PGtkWidget; 
begin 
    SetExceptionMask([exDenormalized, exInvalidOp, exOverflow, 
    exPrecision, exUnderflow, exZeroDivide]); {this is needed for GTK not to crash} 

    gtk_init(@argc, @argv); 

    win:=gtk_window_new(GTK_WINDOW_TOPLEVEL); 

    recordInstance.myInt:=7; 

    button:=gtk_button_new; 

    {The following does not work. The procedure will run when the button is 
    clicked; it will print some number, but not the content of recordInstance.myInt} 
    g_signal_connect_data(button, 'clicked', 
    TGCallback(@recordInstance.testProcedure), nil, nil, 0); 

    {add button to window} 
    gtk_container_add(PGtkContainer(win), button); 

    gtk_widget_show_all(win); 

    {Test call to recordInstance.testProcedure to see that it outputs 
    '7' correctly} 
    recordInstance.testProcedure; 

    gtk_main; 
end. 

當我嘗試使用類或對象,而不是高級的記錄,我收到的實物

"<procedure variable type of procedure of object;CDecl>" to "<procedure variable type of procedure;CDecl>" 

的錯誤信息是使用結構化數據類型與程序爲C回調使用的有什麼辦法在上面的例子中(如果有的話)?

+0

我想C沒有辦法使用方法作爲回調。方法調用必須轉換爲普通的過程調用。請參閱[如何將方法作爲回調傳遞給Windows API調用?](http://stackoverflow.com/q/2787887/576719)。 –

回答

1

類的靜態方法與程序兼容。但他們也有缺點,他們沒有提及對象的數據。

{$mode delphi} 

type 
    myRecord=record 
    public 
     myInt: Integer; 
     class procedure testProcedure; cdecl;static; 
    end; 

    tproctype = procedure; cdecl; 

class procedure myrecord.testProcedure; cdecl;static; 
begin 
end; 

var x : tproctype; 
    y : myrecord; 
begin 
x:=y.testprocedure; 
end. 

編譯,但使用是無菌的,因爲如果它映射到普通的C,其不具有(隱式)OO性質。

相關問題