سؤال

لدي واجهة قمت بتعريفها في لغة C++ والتي يجب الآن تنفيذها في لغة C#.ما هي أفضل طريقة للقيام بذلك؟لا أريد استخدام COM على الإطلاق في تعريف الواجهة الخاصة بي.الطريقة التي قمت بحل هذه المشكلة بها الآن هي الحصول على تعريفين للواجهة، أحدهما في C++ والآخر في C#.ثم أقوم بكشف واجهات C# كخادم COM.كان هذا هو تطبيقي المكتوب بلغة C++ ويمكن الاتصال به في C#.هل هناك على أي حال يمكنني تجنب الاضطرار إلى تحديد التنفيذ الخاص بي في C++ وكذلك C#؟

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

المحلول

إذا كنت على استعداد لاستخدام C++/CLI للتعليمات البرمجية المُدارة بدلاً من C#، فيمكنك فقط استخدام تعريف واجهة C++ الأصلية مباشرة عبر ملف الرأس.مدى سهولة ذلك سيعتمد على ما هو موجود في واجهتك بالضبط - أبسط حالة هي شيء يمكنك استخدامه من لغة C.

ألق نظرة على ماركوس هيج خبير C++/CLI:.NET لمبرمجي Visual C++, ، للحصول على الكثير من المعلومات المفيدة حول دمج C++ الأصلي والمُدار في .NET.

نصائح أخرى

جرعة كبيرة هي أداة رائعة لتغليف فئات C++ بلغات أخرى مثل C#.

لماذا لا تريد استخدام COM؟

لكان هذا هو اقتراحي.لقد عمل التشغيل المتداخل لـ COM جيدًا بالنسبة لي، ولقد استخدمت كائنات وواجهات COM في C# (ما عليك سوى الرجوع إلى كائن COM وسيتم إنشاء الغلاف القابل للاستدعاء في وقت التشغيل تلقائيًا).وبالمثل، فإن وضع علامة على فئة C# كـ "Register for COM interop" قد نجح في الاتجاه المعاكس.

اكتب الواجهة بلغة C++ واستخدم وحدات الماكرو لجعلها تبدو كملف رأس cpp قياسي على نظام UNIX ومثل ملف IDL على نظام التشغيل Windows (إذا لم ينجح ذلك، يمكنك دائمًا كتابة برنامج نصي python/Ruby لإنشاء IDL من ملف رأس C++).

ترجمة IDL لإنشاء typelib.استخدم TypeLib Importer لإنشاء تعريفات الواجهة لـ C# وتنفيذ الواجهات هناك.

اكتب الواجهة في IDL واستخدم أداة لتجميع الواجهة إلى اللغة الهدف.قد تجد مؤشرات لهذا عند النظر في CORBA الذي كان مهتمًا بالتواصل بين اللغات.

/ آلان

الطريقة الأخرى هي استخدام واجهة برمجة التطبيقات "المسطحة" على النمط C.قد تستخدم كذلك extern "C" لمنع التحميل الزائد العرضي.استخدم ملف DEF لتسمية الوظائف المصدرة بشكل صريح، لذلك فهي بالتأكيد غير مزخرفة بأي شكل من الأشكال (يتم "تزيين" وظائف C++ بتشفير أنواع المعلمات في جدول التصدير).

على نظام التشغيل x86، احذر من استدعاء الاصطلاحات.من المحتمل أن تعلن صراحة عن استخدام __stdcall أو __cdecl.نظرًا لأن P/Invocation يُستخدم بشكل أساسي لاستدعاء واجهات برمجة تطبيقات Windows، فإنه يكون افتراضيًا StdCall، لكن C وC++ افتراضيًا هو cdecl، لأن ذلك يدعم varargs.

لقد قمت مؤخرًا بتغليف واجهة COM IRapiStream في واجهة C مسطحة حيث يبدو أن .NET يحاول تحويل IStream إلى وحدة تخزين، الأمر الذي فشل بسبب الخطأ STG_E_UNIMPLEMENTEDFUNCTION.

لم تذكر إصدار .NET الذي تستخدمه، ولكن الأمر الذي نجح معي في استخدام Visual Studio .NET 2003 هو توفير غلاف C# رفيع حول التنفيذ المبسط لفئة C++ الحقيقية:

public __gc class MyClass_Net {
public:
   MyClass_Net()
      :native_ptr_(new MyClass())
   {
   }
   ~MyClass_Net()
   {
      delete native_ptr_;
   }

private:
   MyClass __nogc *native_ptr_;
};

من الواضح أن المرء يفضل استخدام Boost Share_ptr هناك، لكن لم أتمكن مطلقًا من جعلهم يلعبون بشكل جيد مع V.NET 2003...

تقوم الطرق ببساطة بإعادة توجيه أساليب C++ الأساسية من خلال المؤشر.قد يلزم تحويل وسائط الأسلوب.على سبيل المثال، لاستدعاء أسلوب C++ الذي يأخذ سلسلة، فمن المحتمل أن يأخذ الأسلوب C# System.String (System::String in Managed C++).يجب عليك استخدام System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi() للقيام بذلك.

أحد الأشياء اللطيفة في هذا الأسلوب هو أن Managed C++ هي لغة .NET، حيث يمكنك الكشف عن أدوات الوصول كخصائص (__property).يمكنك حتى الكشف عن السمات، تمامًا كما هو الحال في C#.

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