طريقة سريعة (في وقت المطور) لاستخدام الكثير من أكواد C++ من Java

StackOverflow https://stackoverflow.com/questions/1534734

سؤال

خلفية:نحن نعمل على تصميم تطبيق فيزيائي، من شأنه أن يقوم بالكثير من تحليل البيانات، ولكن تركيزنا ينصب على دمج المعدات الإلكترونية المادية.

في الأساس أود أن أكون قادرًا على الاتصال جذر (إنها مكتبة تحليل بيانات كبيرة من CERN مكتوبة بلغة C++) مكتبة مكتوبة في مكتبة C++ من Java.تعد القدرة بشكل أساسي على استخدام فئات ROOT من Java (والقيام بذلك دون إضاعة الكثير من الوقت لتشفير أغلفة JNI) أمرًا رائعًا بالنسبة لنا (إذا كان الأمر صعبًا، فسنستخدم على الأرجح Qt).

يمكنني التفكير في الطرق التالية

  • JNI - كما قلت - لا نريد كتابة أغلفة لكل فصل...
  • جينا - لا توفر JNA تعيينات C++، ولكن C فقط.
  • جرعة كبيرة - لم أستخدمه، لكن سمعت أنه صعب الاستخدام.

أشياء أخرى قد تكون وحيًا:لدينا إمكانية الوصول إلى كود المصدر الجذري، لكننا لا نريد تغييره.نريد أن تكون النتائج محمولة.نود أن نلتزم بالمكتبات المجانية.وكما قلت - سنكون قادرين على استخدام الكثير من كود ROOT من البداية، دون أي ضجة.

هل كانت مفيدة؟

المحلول

مع أي خيار، سوف تحتاج إلى القيام ببعض التغليف.على الرغم من أنك لا ترغب في كتابة مغلفات JNI لكل فئة، يمكنك كتابة فئات C++ ذات مستوى أعلى تشمل مجموعات من الأساليب.ثم تحتاج فقط إلى كتابة أغلفة للفئات ذات المستوى الأعلى (يعمل هذا الأسلوب مع طرق أخرى أيضًا، وليس فقط JNI).

نصائح أخرى

اكتب تطبيق C++ صغيرًا يقرأ مدخلاتك من stdin ويكتب مخرجات إلى stdout.ثم قم بتشغيل العملية من داخل تطبيق Java الخاص بك واقرأ الإخراج من stdout.

هذه هي أفضل طريقة للقيام بذلك بدون JNI (وهذا أمر سهل جدًا)

أوصي أداة إنشاء واجهة djinni من Dropbox.يستخدمونها لتطبيقات الأجهزة المحمولة عبر الأنظمة الأساسية الخاصة بهم لإنشاء واجهات بين واجهة Java (Android) وObjective-C (iOS) ونموذج بيانات C++ الخاص بهم.

الفيسبوك استخدمه أيضا لأحد تطبيقاتهم.لذلك أفترض أنه تم اختباره جيدًا.

شاهد حديثهم في CppCon للحصول على نظرة عامة على ما يفعله.يبدو التواصل بين Java وC++ باستخدام JNI عرضة للأخطاء بشكل خاص.

JNIEasy يدعم تعيين فئات C++ إلى فئات Java POJO ولكنه يكلف 399 يورو.نظرًا لأنك تفضل المكتبات المجانية، فقد ترغب في البحث عن حلول تستخدم شيئًا مثل CORBA.إنها الطريقة الوحيدة لتعيين فئات C++ إلى فئات Java.

يحرر:هل فكرت JAS3, هل هي مكتبة جافا مشابهة للجذر؟

مجرد فكرة ولكن هل يمكنك استخدام Python نظرًا لأن Root يدعمها بالفعل؟قد تصبح ماهرًا بشكل معقول في الوقت الذي يستغرقه تغليف التعليمات البرمجية لـ Java.

فكر في استخدام C# بدلاً من Java.إذا كنت معتادًا على لغة Java، فإن التبديل إلى C# يعد أمرًا سهلاً، وقد حدث بالفعل دعم أفضل بكثير لاستدعاء الكود الأصلي.

ماذا عن كتابة الفئات/الوظائف التي تحتاجها في لغة C++ وتجميعها واستدعاء exec() عليها من Java؟

عندما تقوم باستدعاء رمز C أو C++ من Java عبر JNI أو ما يعادله، فإنك تتعرض لخطر زعزعة استقرار نظام Java الأساسي بسبب مشكلات تتعلق بإدارة الذاكرة و/أو سلامة سلسلة الرسائل على جانب C/C++.

قبل السير في طريق JNI وما إلى ذلك، أعتقد أنه يجب عليك التفكير في بدائل أخرى:

  • أخرج Java من المعادلة وقم بتطبيقها بالكامل في C++ (أو C++ / CC# كما اقترح شخص آخر).
  • قم بإنشاء تطبيق سطر أوامر C++ الذي يقوم بالمهمة التي تحتاج إلى القيام بها باستخدام المكتبة الأصلية، وقم بتشغيل التطبيق باستخدام أحد java.lang.Runtime.exec طُرق.
  • قم بإنشاء غلاف "خادم" في لغة C++ للمكتبة التي تعرض الوظائف التي تحتاجها كبروتوكول مخصص، وقم بترميز جانب Java للتحدث إلى الخادم باستخدام HTTP، أو مآخذ التوصيل الأولية، أو الأنابيب، أو أي مستوى نقل مناسب.

جميع البدائل لها جوانب سلبية، ولكن كذلك JNI / JNA وما شابه؛انظر الفقرة الأولى.

يحرر:عندما تتخذ قرارًا باستخدام JNI/JNA في النظام، فمن المحتمل أن تكون هناك عواقب طويلة المدى.بالإضافة إلى مشكلة الاستقرار، عليك أن تفكر في قابلية النقل (هل ستعمل المكتبة الأصلية على أنظمة التشغيل Windows وLinux وما إلى ذلك)، ومشكلات البناء (من الصعب إنشاء مكتبات أصلية في Ant، ​​وما إلى ذلك)، ومشكلات إصدارات النظام الأساسي (هل ستتم الترقية إلى Java) 7 كسر شيئًا ما؟) ، مهارات المطورين ("Joe" الذي قام بتكامل JNI قد غادر - من يعرف أيضًا Java و C++ و JNI؟).مجموع هذه القضايا (IMO) أكثر أهمية من الوقت اللازم للقيام بالتطوير الأولي.

إذا كان الأمر صعبًا، فمن المرجح أننا سنستخدم كيو تي

لماذا لا تركز على ذلك؟لم تذكر حتى الآن أي أسباب لتفضيل Java.

إذا كان الجزء الأكبر هو جذر المصدر والكود الذي يطلق عليه، ربما تكون أسرع بكثير في القيام بكل ذلك في C++.
نظرًا لأنك على ما يرام مع Qt، فلا ينبغي أن تكون واجهة المستخدم مثيرة للقلق كثيرًا.

يحرر:
لا أستطيع حقًا رؤية أي مزايا لنهج Java - يجب عليك نقل جزء كبير من المصدر إلى منصات أخرى على أي حال، وتضيف تعقيدًا مع طبقة التغليف ويصبح لديك المزيد من التبعيات.

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