No se ha definido ningún procedimiento de clase realize


Solo quiero compartir cómo encontré la solución al error

No se ha definido ningún procedimiento de clase realize

Cuando se ejecuta una aplicación X / Motif C. Estoy publicando esto porque solo encontré una referencia a este problema mientras buscaba en línea, y no contenía soluciones.

Me las arreglé para resolver el problema y quería compartir mis hallazgos si te encuentras con este problema de nuevo (Aviso: No estoy diciendo que mi solución siempre resolverá este tipo de error).

Problema

Encontré este problema mientras ejecutaba un programa simple en C que usaba los conjuntos de herramientas Motif y X Intrínsecamente.

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

El código fuente de C era el siguiente:

#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");
}
Author: Some programmer dude, 2015-09-03

2 answers

Sospeché que el problema podría estar en libXt ya que el símbolo XtRealizeWidget está definido en esa biblioteca. Lo miré usando nm pero todo parecía bien:

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

La "T" significa que el símbolo está en la sección de texto (código) de los archivos objeto que componen la biblioteca libXt, por lo que este símbolo está definido. La ruta para las bibliotecas del sistema también era correcta y solo tenía una sola versión de libXt.

Entonces pensé que el orden en que las bibliotecas se estaban pasando a la gcc linker podría ser la causa y comenzó a leer sobre ello, terminando en este hilo stackoverflow

Después de cambiar el orden de las bibliotecas a:

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

El problema fue resuelto.

Preste atención al orden en el que las bibliotecas y se pasa al enlazador!

 28
Author: Miguel Rentes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:29:54

La respuesta de Martin Simmons (tomado de LessTif FAQ):

Los problemas de orden de vinculación son causados por estos dos símbolos:

vendorShellClassRec
vendorShellWidgetClass

Que se definen Y a los que se hace referencia tanto en -lXm como en -lXt. De alguna manera tienes que convencer al enlazador de usar las definiciones -lXm para satisfacer las referencias tanto en -lXm como en -lXt. No deben utilizarse las definiciones -lXt. Para cargadores dinámicos típicos basados en elf (Linux, Solaris etc), esto se hace pasando '-lXm -lXt' al enlazador, que agrega ambas secciones como SO_NEEDED al ejecutable. En tiempo de ejecución, el cargador dinámico recopila símbolos de cada sección SO_NEEDED en el orden en que los encuentra, descarta los símbolos que ya conoce y luego corrige las referencias en todas las bibliotecas cargadas utilizando esa tabla de símbolos combinada. Para los enlazadores estáticos típicos, también se hace especificando '-lXm -lXt' al enlazador. En este caso, el enlazador extrae algunos .o's de -lXm que contienen símbolos referenciados por el usuario y finalmente terminan extrayendo -lXm:Vendor.o debido a las referencias internas en -lXm. Luego hace lo mismo para -lXt, pero no necesita extraer -lXt:Vendor.o porque no define nada que todavía esté indefinido.

 1
Author: Bass,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-19 12:22:44