Java Jni - توصيل الموارد المخصصة في C مع كائنات Java؟
-
22-09-2019 - |
سؤال
أرغب في تخصيص بعض الذاكرة في C وأبقيها مرتبطة بمثال كائن Java ، مثل هذا:
void configure(JNIEnv *object, jobject obj, ....) {
char *buf = new char[1024];
// associated <buf> with <obj> somehow
}
وبعد ذلك ، حرر الذاكرة عندما يتم جمع كائن Java على القمامة - يمكنني القيام بذلك عن طريق استدعاء وظيفة JNI من اللمسات الأخيرة () طريقة كائن جافا.
والسؤال هو ، كيف يمكنني ربط مؤشر C بكائن Java؟ الحفاظ على طويل حقل في الكائن ويلقي المؤشر إلى طويل؟ هل هناك طريقة أفضل؟
المحلول
بشكل عام ، إذا كنت ترغب في نقل مؤشر من C إلى Java ، فمن المستحسن استخدامه long
بحيث يكون هناك ما يكفي من البتات للحفاظ على قيمة المؤشر في حالة أن النظام الأساسي هو 64 بت.
ثم ، ألق نظرة على ByteBuffer.allocateDirect()
الذي يخلق أ ByteBuffer
مثيل يمكن مشاركة الذاكرة مع C. يمكنك تخصيص مثل هذا المباشر ByteBuffer
من جانب جافا ثم تمريره ك jobject
إلى وظيفة JNI وداخل وظيفة JNI هذه تستخدم GetDirectBufferAddress
وظيفة.
طريقة أخرى هي لف منطقة ذاكرة محلية مع NewDirectByteBuffer
وظيفة JNI من الجانب الأصلي. يمنحك أ jobject
يمكنك العودة إلى جانب Java (انتبه إلى المراجع المحلية والعالمية). انتبه إلى حقيقة أنه بمجرد المباشر ByteBuffer
تم إنشاء الذاكرة الأصلية ، فأنت لا تزال مسؤولاً عن إدارة الذاكرة الأصلية: في مرحلة ما ، سيتعين عليك الاتصال delete buf;
في الرمز الأصلي الخاص بك ، لن تفعل Java ذلك من أجلك.
نصائح أخرى
Java ليس لديه أي مفهوم للمؤشر الأصلي ، لذا فإن تخزينه لفترة طويلة هو الخيار الحقيقي الوحيد. لكن يجب ألا تعتمد على finalize
لتحرير المؤشر. طريقة الانتهاء غير موثوق بها كوسيلة لتنظيف الموارد. يرى هذا السؤال لمزيد من التفاصيل.