Подтвердить что ты не робот

Не определена процедура класса

Я просто хочу поделиться, как я нашел решение ошибки

Не реализована определенная процедура класса

при запуске приложения X/Motif C. Я публикую это, потому что я нашел только одну ссылку на эту проблему во время поиска в Интернете, и в ней не было никаких решений.

Мне удалось решить проблему и захотела поделиться своими выводами, если вы снова столкнетесь с этой проблемой ( Примечание: Я не говорю, что мое решение всегда будет решать этот тип ошибок).

Проблема

Я нашел эту проблему при запуске простой программы на C, которая использовала инструментальные средства Motif и X Intrinsics.

$ gcc -Wall -c push.c
$ gcc -Wall -o push push.o -lXt -lXm
$ ./push
Error: No realize class procedure defined

Исходный код C был следующим:

#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/PushB.h>

/* Prototype Callback function */
void pushed_fn(Widget, XtPointer, XmPushButtonCallbackStruct *);

int main(int argc, char **argv)
{
  Widget top_wid, button;
  XtAppContext  app;
  Display* display;

  XtToolkitInitialize();
  app = XtCreateApplicationContext();
  display = XtOpenDisplay(app, "localhost:10.0","push","push", NULL,0, &argc,argv);
  top_wid = XtAppCreateShell(NULL, "Form", applicationShellWidgetClass, display, NULL, 0);

  button = XmCreatePushButton(top_wid, "Push_me", NULL, 0);

  /* tell Xt to manage button */
  XtManageChild(button);

  /* attach fn to widget */
  XtAddCallback(button, XmNactivateCallback, (XtCallbackProc) pushed_fn, NULL);

  XtRealizeWidget(top_wid); /* display widget hierarchy */
  XtAppMainLoop(app); /* enter processing loop */
  return 0;
}

void pushed_fn(Widget w, XtPointer client_data, XmPushButtonCallbackStruct *cbs)
{
  printf("Don't Push Me!!\n");
}
4b9b3361

Ответ 1

Я подозревал, что проблема может быть в libXt, так как символ XtRealizeWidget определен в этой библиотеке. Я смотрел на него с помощью nm, но все было хорошо:

$ nm -D /usr/lib/libXt.so |grep XtRealizeWidget
02b39870 T XtRealizeWidget

"T" означает, что символ находится в разделе текста (кода) объектных файлов, которые составляют библиотеку libXt, поэтому этот символ определен. Путь к системным библиотекам также был правильным, и у меня была только одна версия libXt.

Тогда я подумал, что порядок, в котором библиотеки передаются в gcc-компоновщик, может быть причиной и начать читать об этом, заканчивая этим fooobar.com/questions/19373/...

После переключения порядка библиотек на:

$ gcc -Wall -o push push.o -lXm -lXt

проблема была решена.

Обратите внимание на порядок, в котором библиотеки и передаются в компоновщик!

Ответ 2

Ответ Мартин Симмонс (взятый из LessTif FAQ):

Проблемы с порядком привязки вызваны этими двумя символами:

vendorShellClassRec
vendorShellWidgetClass

которые определены и указаны как в -lXm, так и -lXt. Как-то вам нужно убедить компоновщика использовать определения -lXm для удовлетворения ссылок как в -lXm, так и в -lXt. Определения -lXt не должны использоваться. Для типичных динамических загрузчиков на основе эльфов (Linux, Solaris и т.д.) Это делается путем передачи '-lXm -lXt' в компоновщик, который добавляет их как к SO_NEEDED в исполняемый файл. Во время выполнения динамический загрузчик собирает символы из каждого раздела SO_NEEDED в том порядке, в котором он их находит, отбрасывая уже известные ему символы, а затем фиксирует ссылки во всех загруженных библиотеках, используя эту комбинированную таблицу символов. Для типичных статических компоновщиков это также делается путем указания '-lXm -lXt' компоновщику. В этом случае компоновщик извлекает некоторые .o из -lXm, которые содержат символы, указанные пользователем, и в конечном итоге заканчивает извлечение -lXm:Vendor.o из-за внутренних ссылок в -lXm. Затем он делает то же самое для -lXt, но не нуждается в извлечении -lXt:Vendor.o, потому что он не определяет ничего, что еще undefined.