2012-10-19 40 views
9

Tôi đang viết thư viện gốc java trong C++ và sử dụng xử lý ngoại lệ trong chính lib tự nhiên, nhưng thư viện bị treo ngay khi tôi ném ngoại lệ. Đây là chương trình thử nghiệm đơn giản của tôi, khi tôi gọi nó từ thử nghiệm Java, nó chỉ bị treo ngay khi ngoại lệ được ném ra. Khối catch không hoạt động. Bất kỳ ý tưởng những gì tôi đang mất tích. Cảm ơn.khối catch không hoạt động trong thư viện gốc C++

#include "Test.h" 
#include <iostream> 

JNIEXPORT void JNICALL Java_Test_helloWorld(JNIEnv *, jobject) 
{ 
    std::cout<<"Hello World"; 
    try { 
     throw 1; 
    } 
    catch(int) 
    { 
     std::cout<<" catch int block"<<std::endl; 
    } 
    catch(...) 
    { 
     std::cout<<" catch block"<<std::endl; 
    } 
} 

Compile và Link:

g++ -m64 -fPIC -fexceptions -c test.cpp 
g++ -shared -m64 -Wl,-soname,libtest.so -Wl,-shared-libgcc test.o -o libtest.so 

$ java -d64 -Djava.library.path=/home/vkumar/projects/test -cp $CLASSPATH Test 
terminate called after throwing an instance of 'int' 
terminate called recursively 
Hello World^CAbort (core dumped) 
+0

những gì nền tảng? nhà cung cấp và phiên bản java nào? –

+0

SunOS 5.10, GCC 4.3.3 và JDK 1.6.0, tôi đã cố gắng biên dịch tất cả ở chế độ 32 bit nhưng có cùng kết quả. – vkumar

+1

Tôi nhớ đã có một vấn đề tương tự cách đây vài năm trên Solaris. Quay lại sau đó, vấn đề đã được sử dụng GCC, liên kết GNU và thư viện được chia sẻ. Chúng tôi đã giải quyết vấn đề bằng cách sử dụng trình liên kết Mặt trời và bằng cách liên kết đến các tệp nhị phân tĩnh. Rõ ràng, việc thực hiện try/catch của GCC cần sự hỗ trợ liên kết không tương thích với trình liên kết động Sun. Bạn có thể thử sử dụng một trình liên kết khác, vì việc chuyển đổi tĩnh sẽ không giúp ích trong môi trường Java. – h2stein

Trả lời

1

tôi đã cố gắng examplea của bạn và tất cả mọi thứ diễn ra tốt đẹp. Môi trường của tôi là Ubuntu 12.04 (64bit) với Oracle JDK 1.7.

Vì vậy, tôi đoán là môi trường của bạn là thủ phạm. Vì bạn sử dụng tùy chọn -m64, nó có thể không khớp giữa hệ thống 32 bit và libtest.so 64 bit.

Vui lòng xác minh hệ thống của bạn, JDK, gcc, v.v. phù hợp với nhau.

+0

Cảm ơn, tôi sẽ kiểm tra tính tương thích giữa tất cả các thành phần liên quan. Tôi đang sử dụng Solaris 5.10, gcc 4.3.3 và jdk 1.6 – vkumar

+0

@vkumar Tôi đã thử lại với OpenJDK 6 và OpenJDK 7 (gcc 4.6.3). Cùng một kết quả: thành công. –

+0

Cảm ơn Olaf, tôi sẽ thử với phiên bản GCC khác. Mục tiêu của chúng tôi là Sun Solaris, tôi sẽ không thể thay đổi điều đó. Nhưng nếu vấn đề trình biên dịch của nó, tôi luôn có thể nâng cấp nó. Cảm ơn một lần nữa. – vkumar

0

Dường như ngoại lệ là không bị bắt. Hãy thử

int i=1; 

try { 
    throw i; 
} 

có thể là vấn đề với kích thước int hoặc gì đó? Hoặc bạn quên biên dịch lại?

+0

Không, tôi đảm bảo rằng tôi đã xóa .so, .o và biên dịch lại mọi thứ. ngay cả khi có vấn đề với kích thước int bắt (...) nên bắt nó. – vkumar

0

JNIExport hoặc JNICALL có đang mở rộng để xác định liên kết c không? nếu vậy thì bạn đang ném một ngoại lệ C++ trong một hàm c và tôi không chắc chắn rằng hành vi được định nghĩa.

có thể thử một cái gì đó giống như

namespace 
{ 
    void impl() 
    { 
    ... yourCode ... 
    } 
} 

JNIEXPORT void JNICALL Java_Test_helloWorld(JNIEnv *, jobject) 
{ 
    impl(); 
} 
+0

Nó không phải là một vấn đề để ném và bắt một ngoại lệ trong một chức năng "C" bên ngoài. Nó sẽ là một vấn đề để cho phép thoát ngoại lệ cho biết chức năng. –

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