使用结构化数据类型的过程作为 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 属性。