2015-09-03 27 views
31

Tôi chỉ muốn chia sẻ làm thế nào tôi tìm thấy giải pháp cho lỗiKhông thủ tục lớp nhận ra định nghĩa

Không thủ tục lớp nhận ra định nghĩa

khi chạy một/Motif C ứng dụng X. Tôi đăng bài này bởi vì tôi chỉ tìm thấy một tham chiếu đến vấn đề này trong khi tìm kiếm trực tuyến, và nó không chứa các giải pháp.

tôi quản lý để giải quyết vấn đề và muốn chia sẻ những phát hiện của tôi nếu bạn gặp vấn đề này một lần nữa (Chú ý: Tôi không nói rằng giải pháp của tôi sẽ luôn giải quyết kiểu này lỗi).

Vấn đề

tôi thấy vấn đề này trong khi chạy một chương trình C đơn giản mà sử dụng bộ công cụ Motif và X Intrinsics.

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

Mã nguồn C là như sau:

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

Trả lời

28

tôi nghi ngờ vấn đề có thể nằm trên libXt kể từ khi biểu tượng XtRealizeWidget được định nghĩa trong thư viện đó. Tôi nhìn nó bằng cách sử nm nhưng tất cả dường như tốt:

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

Các "T" là biểu tượng là trong văn bản (code) phần của các tập tin đối tượng soạn thư viện libXt, vì vậy biểu tượng này được xác định. Đường dẫn cho các thư viện hệ thống cũng đúng và tôi chỉ có một phiên bản libXt duy nhất.

sau đó tôi nghĩ rằng thứ tự mà các thư viện đã được truyền lại cho các mối liên kết gcc có thể là nguyên nhân gây ra và bắt đầu đọc về nó, kết thúc lên trên này stackoverflow thread

Sau khi chuyển đổi thứ tự của các thư viện để:

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

sự cố đã được giải quyết.

Chú ý đến thứ tự thư viện và được chuyển tới trình liên kết!

+1

Mặc dù tôi không thể đưa tham chiếu chính xác đến hướng dẫn lập trình X11/Motif, tôi khá chắc chắn nhiều hướng dẫn/hướng dẫn đặt thẳng: 'lXm' phải được liên kết trước' lXt' và 'lX11'. Ít nhất, * LessTif * FAQ có [chú thích] tương ứng (http://lesstif.sourceforge.net/FAQ.html#QU3.0). Xem thêm Debian này [bug report] (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=718691) (có rất nhiều chúng). – Bass

1

Câu trả lời bởi Martin Simmons (lấy từ LessTif FAQ):

Các liên kết các vấn đề trật tự được gây ra bởi hai biểu tượng sau đây:

vendorShellClassRec 
vendorShellWidgetClass 

được định nghĩa tham chiếu trong cả hai -lXm-lXt. Bằng cách nào đó bạn phải thuyết phục người liên kết sử dụng các định nghĩa -lXm để đáp ứng các tham chiếu trong cả hai -lXm-lXt. Các định nghĩa -lXt không nên được sử dụng. Đối với các trình nạp động cơ bản địa điển hình (Linux, Solaris v.v.), điều này được thực hiện bằng cách chuyển '-lXm -lXt' tới trình liên kết, thêm chúng làm SO_NEEDED phần thực thi.Khi chạy, trình nạp động thu thập các ký hiệu từ mỗi phần SO_NEEDED theo thứ tự tìm thấy chúng, loại bỏ các ký hiệu mà nó đã biết và sau đó sửa các tham chiếu trong tất cả các thư viện được tải bằng bảng ký hiệu kết hợp đó. Đối với các liên kết tĩnh điển hình, nó cũng được thực hiện bằng cách chỉ định '-lXm -lXt' cho trình liên kết. Trong trường hợp này, trình liên kết trích xuất một số .o từ -lXm chứa ký hiệu do người dùng tham chiếu và cuối cùng kết thúc bằng cách trích xuất -lXm:Vendor.o do tham chiếu nội bộ trong -lXm. Sau đó nó làm tương tự cho -lXt, nhưng không cần phải trích xuất -lXt:Vendor.o vì nó không xác định bất kỳ thứ gì vẫn chưa được xác định.

Các vấn đề liên quan