2012-02-28 52 views
9

Tôi đang sử dụng Java cho một ứng dụng nhỏ. Đó là một viết lại của một dự án MFC hiện có. Có một dll hiện có mà tôi cần thay đổi để cho phép truy cập từ Java bằng JNI. Tất cả các công cụ Java này là mới đối với tôi, vì vậy tôi gặp một chút rắc rối và cảm thấy khá dày đặc khi tôi đọc các bài đăng trên diễn đàn khác. Trong dll hiện có, tôi có một chức năng như sau:Gọi C++ dll từ Java

extern "C" __declspec(dllexport) bool Create() 
{ 
    return TRUE; 
} 

Thời gian hỏi câm. Làm thế nào để tôi thiết lập đúng cách để được gọi bằng Java?

Tôi cố gắng này:

JNIEXPORT jboolean JNICALL Create() 
{ 
    return TRUE; 
} 

tôi bao gồm tất cả mọi thứ jni.h và biên dịch tốt. Tuy nhiên, khi tôi gọi nó từ Java, tôi nhận được UnsatisfiedLinkError. Tôi đang gọi nó từ Java bằng cách sử dụng này:

public static native boolean CreateSession(); 

System.load("D:\\JavaCallTest.dll"); 
Create(); 

Ai đó có thể đưa tôi đi đúng hướng không? Tôi chân thành cảm kích sự giúp đỡ nào.

Cảm ơn,

Nick

+1

Bạn đã xem ví dụ về Mặt trời chưa? http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html – Etienne

+1

Ngoài ra, bạn có thể sử dụng JNA thay vì JNI vì bạn có một dll C có thể được tải bởi JNA. – ecle

+0

Vui lòng đăng ngoại lệ được ném ... – quaylar

Trả lời

7

Bạn cần phải bao gồm tên lớp Java và đường dẫn trong mã nguồn gốc của mình, ví dụ nếu phương pháp tự nhiên của bạn đã khai báo trong Java như:

public class NativeCode { 
    public static native boolean CreateSession(); 
} 

và đường dẫn lớp là (ví dụ) com.example.NativeCode bạn sẽ khai báo phương pháp của bạn ở dạng gốc như sau:

extern "C" 
JNIEXPORT jboolean JNICALL Java_com_example_NativeCode_CreateSession(JniEnv* env, jclass clazz) 
{ 
    return JNI_TRUE; 
} 

Tất cả các phương thức JNI đều có hai tham số JNIEnv đầu tiên.

+0

Đó là nó. Nó có vẻ đang hoạt động. Chúng tôi sẽ xem những loại vấn đề tôi gặp phải khi tôi không giao dịch với một chức năng đơn giản như thế này. Tôi đánh giá cao sự giúp đỡ. – nickfinity

+0

@GooseSerbus những gì về các tham số được sử dụng công cộng tĩnh boolean CreateSession (?,?); Các tham số – Aniket

+0

@Aniket được thêm vào các tham số trong phương thức C, ví dụ: 'public static boolean CreateSession (boolean, Object);' sẽ là 'JNIEXPORT jboolean JNICALL Java_com_example_NativeCode_CreateSession (JniEnv * env, jclass clazz, jboolean b, jobject o) ' – GooseSerbus

1

Tôi đã có một vấn đề tương tự - một C-codebase hiện mà tôi cần thiết để truy cập từ Java. Nó trả tiền cho tôi, để làm quen với SWIG, một công cụ để tạo ra một DLL trung gian C++ (gọi là C-Code), cộng với Java-Code đang gọi vào C++ DLL.

Nếu bạn có nhiều hơn chỉ là 1 chức năng của DLL để bọc, nó có thể trả hết để kiểm tra công cụ này, nếu không bạn sẽ phải làm quen với JNI ...

EDIT:

Dường như tệp DLL của bạn không được tìm thấy theo lệnh gọi System.load(). Bạn có thể muốn thử System.loadLibrary(), nhưng lưu ý rằng DLL của bạn sau đó phải được đặt trong đường dẫn được biểu thị bởi thuộc tính hệ thống Java java.library.path. Cũng không vượt qua tên tệp đầy đủ trong trường hợp này, nhưng chỉ tên tệp mà không có phần mở rộng.

+0

Nó đã được tìm thấy DLL, nhưng tôi đã không có chức năng của tôi đúng tuyên bố. Tôi sẽ phải nhìn vào SWIG. Cảm ơn vì tiền hỗ trợ. – nickfinity

2

Một phương pháp bản địa tĩnh vẫn cần ít nhất hai tham số:

JNIEnv *env 
jclass clazz 

Tên chức năng cũng phải tương ứng với cấu trúc gói java.

JNIEXPORT jboolean JNICALL Java_com_example_CreateSession(JNIEnv *env, jclass clazz) 

Tốt nhất, bạn sẽ sử dụng công cụ javah để tạo ra một tập tin tiêu đề từ lớp java tuyên bố phương pháp tự nhiên và sau đó thực hiện các nguyên mẫu hàm tuyên bố.

+0

+1 để đề cập rằng javah nên được sử dụng để tạo ra các chữ ký chức năng. –

+0

Tìm thấy điều này (http://stackoverflow.com/a/3452258/978528) và thiết lập Eclipse để chạy javah. Làm việc tốt ngay bây giờ. Bây giờ tôi phải thực hiện phần còn lại của công cụ. Hy vọng rằng sẽ được đơn giản. – nickfinity

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