【问题标题】:No realize class procedure defined没有定义实现类过程
【发布时间】:2015-11-29 04:11:18
【问题描述】:

我只是想分享我如何找到错误的解决方案

没有定义实现类过程

在运行 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");
}

【问题讨论】:

    标签: c gcc x11 ld motif


    【解决方案1】:

    我怀疑问题可能出在 libXt 上,因为 XtRealizeWidget 符号是在该库中定义的。我用 nm 查看了它,但一切似乎都很好:

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

    “T”表示符号位于组成 libXt 库的目标文件的文本(代码)部分中,因此定义了该符号。系统库的路径也正确,我只有一个版本的 libXt。

    然后我认为将库传递给 gcc 链接器的顺序可能是原因并开始阅读有关它的内容,最后看到了 stackoverflow thread

    将库的顺序切换为:

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

    问题解决了。

    注意库和传递给链接器的顺序!

    【讨论】:

    • 虽然我不能提供 X11/Motif 编程手册的确切参考,但我很确定许多手册/教程都直截了当:lXm 应该在 lXt 和 @987654328 之前链接@。至少,LessTif FAQ 有对应的note。另请参阅这个 Debian bug report(有很多)。
    【解决方案2】:

    Martin Simmons 的回答(取自LessTif FAQ):

    链接顺序问题是由这两个符号引起的:

    vendorShellClassRec
    vendorShellWidgetClass
    

    -lXm-lXt 中都定义了AND。您必须以某种方式说服链接器使用-lXm 定义来满足-lXm-lXt 中的引用。不应使用 -lXt 定义。对于典型的基于 elf 的动态加载器(LinuxSolaris 等),这是通过将 '-lXm -lXt' 传递给链接器来完成的,链接器将它们都作为 SO_NEEDED 部分添加到可执行文件。在运行时,动态加载器按照找到它们的顺序从每个SO_NEEDED 部分收集符号,丢弃它已经知道的符号,然后使用该组合符号表修复所有已加载库中的引用。对于典型的静态链接器,也可以通过将'-lXm -lXt' 指定给链接器来完成。在这种情况下,链接器从包含用户引用符号的-lXm 中提取一些.o,并最终由于-lXm 中的内部引用而最终提取-lXm:Vendor.o。然后它对-lXt 执行相同的操作,但不需要提取-lXt:Vendor.o,因为它没有定义任何仍未定义的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      • 2012-10-22
      相关资源
      最近更新 更多