سؤال

أرغب في تخصيص بعض الذاكرة في 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 لتحرير المؤشر. طريقة الانتهاء غير موثوق بها كوسيلة لتنظيف الموارد. يرى هذا السؤال لمزيد من التفاصيل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top