cgccx11ldmotif

No realize class procedure defined


I just want to share how I found the solution to the error

No realize class procedure defined

when running a X/Motif C application. I am posting this because I only found one reference to this problem while searching online, and it contained no solutions.

I managed to solve the problem and wanted to share my findings if you do come across this problem again (Notice: I am not saying my solution will always solve this type of error).

Problem

I found this problem while running a simple C program that used the Motif and X Intrinsics toolkits.

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

The C source code was the following:

#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");
}

Solution

  • I suspected the problem could be on the libXt since the XtRealizeWidget symbol is defined in that library. I looked at it using nm but all seemed well:

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

    The "T" means the symbol is in the text (code) section of the object files that compose the libXt library, so this symbol is defined. The path for the system libraries was also correct and I only had a single version of libXt.

    I then thought that the order in which the libraries were being passed on to the gcc linker might be the cause and started reading about it, ending up on this stackoverflow thread

    After switching the order of the libraries to:

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

    the problem was solved.

    Pay attention to the order in which the libraries and being passed to the linker!