2010-07-30 24 views
5

Tôi đang định nghĩa một lớp java từ C với lời gọi JNI DefineClass() và sau đó tôi đăng ký gọi lại gốc cho các phương thức trong lớp tự nhiên. Lớp này có hai phương thức tĩnh, cả hai đều là native. Tôi sử dụng RegisterNatives() để đăng ký các hàm gốc. Cả hai cuộc gọi đều thành công.Tôi đang định nghĩa một lớp Java từ C với DefineClass() nhưng nhận được UnsatisfiedLinkError

Nhưng khi tôi tham khảo những phương pháp có nguồn gốc từ mã Java của tôi tôi nhận được java.lang.UnsatisfiedLinkError myPackage.myClass.myMethod (I) V

Nhưng tôi biết rằng DefineClass trở một đối tượng lớp cho myPackage.myClass và tôi biết rằng myMethod (I) V đã được đăng ký làm phương thức cho lớp đó.

Tôi nhận được lỗi này cũng giống như sắp thực hiện lệnh main() - khi cuộc gọi đến phương thức gốc của tôi là (hiện tại, để kiểm tra).

Là một thử nghiệm, tôi đã thử gọi DefineClass hai lần trên cùng một JNIEnv để xem điều gì đã xảy ra. Tôi nhận được một lỗi định nghĩa lớp trùng lặp. Tôi cũng đã thử gọi FindClass() sau khi xác định nó và JNIEnv trả về một tham chiếu đến lớp đã định nghĩa.

Vì vậy, tôi tạo độ ổn định cho lớp một cách linh hoạt, nhưng nó không thành công khi tôi cố gắng tham khảo các phương pháp của nó.

Bất kỳ ý tưởng nào? Tất cả đầu vào đều được đánh giá cao.

Nền tảng: Windows, 32 bit mã trên 64 bit XP.

+0

Bạn có thể có phiên bản dll cũ hơn ở đâu đó trong đường dẫn của mình không? –

+0

Khi bạn biên soạn DLL của bạn, bạn đã xuất các chức năng? –

+0

Romain: Chức năng của tôi không cần xuất và phiên bản DLL không liên quan - DLL đăng ký các chức năng với RegisterNatives() là DLL cung cấp các chức năng. Các hàm theo định nghĩa có sẵn tại thời điểm RegisterNatives() được gọi. –

Trả lời

2

Dường như bạn không thể xác định phương thức gốc bằng cách sử dụng DefineClass() và gọi phương thức gốc đó trực tiếp từ mã được tiêm của bạn. Bạn phải có một phương pháp trampoline trong lớp tiêm của bạn (dưới dạng mã byte Java) mà sau đó gọi phương thức gốc của bạn. Chỉ sau đó nó sẽ hoạt động. Đã cho tôi ba ngày để làm việc đó.

Bíp khác là đảm bảo rằng mã được tiêm của bạn hợp lệ. Mã tôi đã cố gắng nhìn có giá trị, nhưng trên kiểm tra chặt chẽ hơn tôi đã kéo một 4 byte kích thước liên tục từ các hồ bơi liên tục như là một toán hạng cho một hướng dẫn 8 byte. Vì vậy, điều đó không thành công. Một khi đã được cố định (và trampoline bản địa), tất cả đều hoạt động.

Tuy nhiên để đến đó thông qua tất cả các hoán vị khác nhau, tôi đã phải thử mất 3 ngày. Cảm thấy tốt khi làm việc mặc dù.

Làm cách nào để làm tấm bạt lò xo? Xem các ví dụ (trong C) đi kèm với SDK Java. Chúng khá dài và không thích hợp để đăng ở đây.

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