Я пытаюсь использовать процедуры в структурированном типе данных в качестве функций обратного вызова для программы с использованием GTK + 3 в качестве своего инструментария в FreePascal. (GTK + 3 привязки я был сгенерирован инструментом gir2pascal (http://wiki.freepascal.org/gir2pascal))Использование процедуры в структурированном типе данных в качестве обратного вызова для библиотеки C (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.
Когда я пытаюсь использовать классы или объекты вместо Advanced Запись, я получаю сообщения об ошибках типа
"<procedure variable type of procedure of object;CDecl>" to "<procedure variable type of procedure;CDecl>"
Какие есть пути использования структурированного типа данных с процедурой, чтобы использовать в качестве обратного вызова C, как в приведенном выше примере (если таковой имеется)?
Я полагаю, что C не имеет способа использовать метод в качестве обратного вызова. Вызов метода должен быть преобразован в обычный вызов процедуры. См. [Как передать метод как ответ на вызов Windows API?] (Http://stackoverflow.com/q/2787887/576719). –