31

エラーの解決策を見つけた方法を共有したいだけです

実現クラス プロシージャが定義されていません

X/Motif C アプリケーションの実行時。オンラインで検索したときにこの問題への参照が 1 つしか見つからず、解決策が含まれていなかったため、これを投稿しています。

私はなんとか問題を解決し、この問題に再び遭遇した場合は私の発見を共有したいと思いました (注意:私の解決策が常にこの種のエラーを解決すると言っているわけではありません)。

問題

この問題は、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");
}
4

2 に答える 2

28

XtRealizeWidget シンボルがそのライブラリで定義されているため、libXt に問題があるのではないかと考えました。nm を使用して調べましたが、すべて問題ないように見えました。

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

「T」はシンボルが libXt ライブラリを構成するオブジェクト ファイルのテキスト (コード) セクションにあることを意味するため、このシンボルが定義されます。システム ライブラリのパスも正しく、libXt のバージョンは 1 つしかありませんでした。

次に、ライブラリが gcc リンカーに渡される順序が原因である可能性があると考え、それについて読み始め、このスタックオーバーフロー スレッドにたどり着きました。

ライブラリの順序を次のように切り替えた後:

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

問題は解決しました。

ライブラリとリンカーに渡される順序に注意してください。

于 2015-09-03T10:56:40.283 に答える
1

Martin Simmonsによる回答( LessTif FAQから取得):

リンク順序の問題は、次の 2 つのシンボルによって引き起こされます。

vendorShellClassRec
vendorShellWidgetClass

これらは、 と の両方で定義および参照されています。と の両方の参照を満たすために、何らかの方法でリンカーに定義を使用するよう説得する必要があります。定義は使用しないでください。典型的な elf ベースの動的ローダー ( LinuxSolarisなど) の場合、これはリンカーに渡すことによって行われ、リンカーは両方をセクションとして実行可能ファイルに追加します。実行時に、ダイナミック ローダーは各セクションからシンボルを見つけた順に収集し、既に認識しているシンボルを破棄してから、結合されたシンボル テーブルを使用して、読み込まれたすべてのライブラリの参照を修正します。典型的な静的リンカーの場合、指定することによっても行われます-lXm-lXt-lXm-lXm-lXt-lXt'-lXm -lXt'SO_NEEDEDSO_NEEDED'-lXm -lXt'リンカーに。この場合、リンカーは、ユーザー参照シンボルを含むいくつか.oの を抽出し-lXm、最終的には-lXm:Vendor.oの内部参照のために抽出を終了し-lXmます。次に、 に対して同じことを行いますが、未定義のものは何も定義しないため-lXt、抽出する必要はありません。-lXt:Vendor.o

于 2015-10-19T12:22:44.510 に答える