使用结构化数据类型的过程作为 C 库的回调 (GTK+3)
Using procedure in structured data type as callback for C library (GTK+3)
我正在尝试使用结构化数据类型中的过程作为程序的回调函数,该程序使用 GTK+3 作为 FreePascal 中的工具包。 (我拥有的 GTK+3 绑定是由 gir2pascal 工具生成的 (http://wiki.freepascal.org/gir2pascal))
在下面的示例中,我使用了高级记录,但我肯定会考虑 类 或对象,如果它们都适用 better/at。
出现的问题是调用回调过程时,它无法访问自己记录中的任何其他内容。好像是"forget"从哪里来的
例如,在下面的示例中,我有一个整数 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 回调(如果有)?
class 静态方法与过程兼容。但是它们也有缺点,就是没有对象数据的引用。
{$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 属性。
我正在尝试使用结构化数据类型中的过程作为程序的回调函数,该程序使用 GTK+3 作为 FreePascal 中的工具包。 (我拥有的 GTK+3 绑定是由 gir2pascal 工具生成的 (http://wiki.freepascal.org/gir2pascal))
在下面的示例中,我使用了高级记录,但我肯定会考虑 类 或对象,如果它们都适用 better/at。
出现的问题是调用回调过程时,它无法访问自己记录中的任何其他内容。好像是"forget"从哪里来的
例如,在下面的示例中,我有一个整数 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 回调(如果有)?
class 静态方法与过程兼容。但是它们也有缺点,就是没有对象数据的引用。
{$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 属性。