我只是想分享我是如何找到解决这个错误的方法的
没有实现类过程定义
在运行X/Motif C应用程序时。我张贴这个,因为我只发现一个参考这个问题,而在网上搜索,它包含没有解决方案。
我设法解决了这个问题,如果你再次遇到这个问题,我想分享我的发现(注意:我不是说我的解决方案将总是解决这种类型的错误)。
我在运行一个使用Motif和X Intrinsics工具包的简单C程序时发现了这个问题。
$ 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");
}
我怀疑问题可能出在libXt上,因为XtRealizeWidget符号是在该库中定义的。我用nm看了看,但一切似乎都很好:
$ nm -D /usr/lib/libXt.so |grep XtRealizeWidget
02b39870 T XtRealizeWidget
"T"表示该符号位于组成libXt库的目标文件的文本(代码)部分中,因此定义了该符号。系统库的路径也是正确的,而且我只有一个版本的libXt。
然后我认为库被传递给gcc链接器的顺序可能是原因,并开始阅读它,最终在这个stackoverflow线程
将库的顺序切换为:
$ gcc -Wall -o push push.o -lXm -lXt
问题解决了。
注意传递给链接器的库和的顺序!
Martin Simmons的回答(摘自LessTif FAQ):
链接顺序问题是由这两个符号引起的:
vendorShellClassRec vendorShellWidgetClass
在
-lXm
和-lXt
中定义为和。不知何故,您必须说服链接器使用-lXm
定义来满足-lXm
和-lXt
中的引用。不应该使用-lXt
定义。对于典型的基于elf的动态加载器(Linux, Solaris等),这是通过将'-lXm -lXt'
传递给链接器来完成的,链接器将它们作为SO_NEEDED
节添加到可执行文件中。在运行时,动态加载器按照找到符号的顺序从每个SO_NEEDED
节中收集符号,丢弃它已经知道的符号,然后使用组合符号表修复所有加载库中的引用。对于典型的静态链接器,也可以通过向链接器指定'-lXm -lXt'
来完成。在这种情况下,链接器从-lXm
中提取了一些包含用户引用符号的.o
,最终由于-lXm
中的内部引用而最终提取了-lXm:Vendor.o
。然后对-lXt
执行相同的操作,但不需要提取-lXt:Vendor.o
,因为它不定义任何尚未定义的内容。