Trong java, phương thức tĩnh riêng tư registerNatives()
của lớp Object làm gì?Phương thức registerNatives() làm gì?
Trả lời
Các câu trả lời khác là chính xác về mặt kỹ thuật, nhưng không hữu ích cho người không có kinh nghiệm JNI. :-)
Thông thường, để JVM tìm thấy các hàm gốc của bạn, chúng phải được đặt tên theo một cách nhất định. ví dụ: đối với java.lang.Object.registerNatives
, hàm C tương ứng có tên là Java_java_lang_Object_registerNatives
. Bằng cách sử dụng registerNatives
(hoặc đúng hơn, chức năng JNI RegisterNatives
), bạn có thể đặt tên cho hàm C của mình bất cứ điều gì bạn muốn.
Dưới đây là đoạn code liên quan đến C (từ OpenJDK 6):
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
(Chú ý rằng Object.getClass
không có trong danh sách, nó vẫn sẽ được gọi bằng cái tên "tiêu chuẩn" của Java_java_lang_Object_getClass
.) Đối với các chức năng được liệt kê, các hàm C được liên kết như được liệt kê trong bảng đó, đó là thủ công hơn là viết một loạt các chức năng chuyển tiếp.
Đăng ký chức năng gốc cũng hữu ích nếu bạn đang nhúng Java vào chương trình C và muốn liên kết đến các hàm trong chính ứng dụng (trái ngược với thư viện dùng chung) hoặc các chức năng đang được sử dụng không được xuất ", vì chúng thường không được tìm thấy bởi cơ chế tra cứu phương pháp chuẩn. Việc đăng ký các hàm gốc cũng có thể được sử dụng để "rebind" một phương thức gốc sang một hàm C khác (hữu ích nếu chương trình của bạn hỗ trợ các mô-đun tải và nạp tự động, chẳng hạn).
Tôi khuyến khích mọi người đọc JNI book, nói về điều này và hơn thế nữa. :-)
Bạn đã viết tên chức năng JNI được trang trí đầy đủ, điều này làm cho nó khó hiểu: là 'Java_java_lang_Object_registerNatives' được VM tự động gọi, hoặc mã c/C++ phải gọi hàm đó và không cần tất cả java gobblygook – Pavel
@Pavel Theo mặc định, phương thức native 'methodName' trong lớp' fully.qualified.ClassName' được tìm kiếm dưới tên C 'Java_fully_qualified_ClassName_methodName' (mà mã C-side của bạn phải xuất). Bạn có thể gọi phương thức 'RegisterNatives' của' JNIEnv' để ghi đè liên kết này. Nói cách khác, nếu bạn không sử dụng 'RegisterNatives' trước," tất cả java gobblygook "[sic] là bắt buộc. –
Ah, ok, do đó, bằng cách xuất chỉ có 1 hàm 'Java_java_lang_Object_registerNatives' tôi thực sự có thể liên kết tất cả các công cụ JNI của tôi bằng cách kiểm tra giá trị của' cls'. Tôi đã bỏ lỡ phần registerNatives thực sự là một phần của java. Vì vậy, ... khi một số lớp sắp được sử dụng, thứ tự các hành động mà JVM sử dụng để liên kết người bản địa là gì? Dường như nếu người bản địa chưa đăng ký (từ c/C++), thì JVM sẽ kiểm tra tất cả các tên đã xuất này, nếu chúng không có mặt thì nó sẽ cố gắng sử dụng Object.registerNatives (hoặc cách khác xung quanh?). Nhân tiện, liên kết sách jni đã chết. – Pavel
Vì bạn đã xem mã nguồn để tìm nó, nó khá dễ đoán?
Đó là một phương pháp gốc và được gọi là registerNatives, vì vậy tôi đoán nó đăng ký các đối tượng với nền tảng cơ bản.
Nó cũng là riêng tư, vì vậy có thể không có gì phải lo lắng.
Bạn phải là một lập trình viên nguồn đóng ("di chuyển theo, không có gì để xem xét"), không được sử dụng cho ý tưởng của những người thực sự muốn biết những gì diễn ra "dưới sự che phủ". Đủ rồi. :-P –
Darn, rõ ràng phải không? – aberrant80
Điều gì có thể hơi khó hiểu là mã được hiển thị cho java.lang.Object.registerNatives
trong câu trả lời trước chỉ là một ví dụ về cách đăng ký chức năng gốc. Đây là mã mà (trong việc thực hiện OpenJDK) đăng ký các hàm gốc cho đối tượng lớp. Để đăng ký các hàm gốc cho lớp của riêng bạn, bạn phải gọi hàm JNI RegisterNatives
từ mã gốc trong thư viện của riêng bạn. Điều này nghe có vẻ hơi tròn, nhưng có một vài cách để phá vỡ vòng lặp.
Thực hiện theo các ví dụ về thực hiện này của lớp Object:
a. Trong lớp Java của bạn, khai báo một phương thức nguyên gốc (tốt nhất là static) có tên là
registerNatives
(hoặc bất kỳ tên nào khác. Nó không quan trọng).b. Trong mã gốc của bạn, hãy xác định hàm có tên
Java_<your fully qualified class name>_registerNatives
, trong đó có cuộc gọi đến hàm JNIRegisterNatives
.c. Đảm bảo rằng trong mã Java của bạn, phương thức Java
registerNatives
của bạn được gọi trước khi có bất kỳ cuộc gọi nào đến các phương thức gốc khác.
HOẶC
Sử dụng
JNI_OnLoad
a. Trong thư viện gốc của bạn, hãy xác định hàm
jint JNI_OnLoad(JavaVM *vm, void *reserved)
. Trong phần thân của hàm này, hãy gọi hàm JNIRegisterNatives
.b. Máy ảo Java sẽ tự động tìm kiếm và gọi
JNI_OnLoad
khi thư viện gốc của bạn được tải bởiSystem.loadLibrary
, mà bạn nên đã gọi, có thể trong trình khởi tạo tĩnh cho lớp của bạn. (Bạn nhận được các yêu cầuenv
con trỏ bằng cách gọiGetEnv
chức năng trong bảng rằngvm
điểm con trỏ đến.)
- 1. Phương thức UnityContainer.Teardown nên làm gì?
- 2. Phương thức Lambda Expression Compile() làm gì?
- 3. Phương thức scrollTo JavaScript không làm gì?
- 4. Android: phương thức "setTextFilterEnabled" làm gì?
- 5. Phương thức getUTC * trên đối tượng ngày làm gì?
- 6. Tên phương thức trống, điều này thực sự làm gì?
- 7. Phương thức ghi Authlogic. Điều này làm gì
- 8. Phương thức __init __() của đối tượng làm gì trong python?
- 9. Phương thức 'on_sym' của Ruby on Rails làm gì?
- 10. Phương thức .dispose() có làm được gì không?
- 11. Phương thức xả của OutputStream không làm gì?
- 12. sự khác nhau giữa phương thức chuỗi và phương thức str trong Python là gì?
- 13. Phương thức "this()" này có nghĩa là gì?
- 14. Có gì sai với phương thức trực tiếp của jQuery?
- 15. Khi phương thức Perl trả về "hashref" nghĩa là gì?
- 16. Phương thức CFString của UTF8String của NSString là gì?
- 17. Phương thức `close()` của Tuyên bố Mysqli là gì?
- 18. Lý do cho phương thức size() của BitSet là gì?
- 19. Mục đích của phương thức Expression.Quote của LINQ là gì?
- 20. Chế độ chọn lựa phương thức là gì?
- 21. Phương thức lưu trữ này được gọi là gì?
- 22. Phương thức đại biểu và ủy quyền là gì
- 23. Trình đơn ngữ cảnh & phương thức registerForContextMenu là gì()
- 24. Gọi phương thức ảo trong java là gì?
- 25. Phương thức getCSSCanvasContext() của phần tử HTML5 là gì?
- 26. Hiệu suất của phương thức STL bitset :: count() là gì?
- 27. Ý nghĩa của phương thức Thread.Join trong C# là gì?
- 28. Cách sử dụng phương thức Pattern.quote là gì?
- 29. "tạo phương thức" có nghĩa là gì trong C#?
- 30. Làm cách nào để ghi đè phương thức __call__ của đối tượng phương thức bằng Python?
Ah tất nhiên, tôi đã không được xem xét các khía cạnh JNI ... Cảm ơn tất cả mọi người! – Hubris