كيف تسمي lib مكتوبة في C ++ من C؟
-
26-09-2019 - |
سؤال
يبدو لي كأنه غير عقلاني ، لكن لا يمكنني العثور على أي معلومات ضد أو من أجل ذلك.
من وجهة نظر الإله إلى الخ ، لا أفترض أن هذا يمثل مشكلة كبيرة ، لكن لا يمكنني معرفة ذلك ، كيف يمكنني كتابة برنامج C صغير جدًا يطلق على وظيفة من مكتبة C ++ صغيرة جدًا.
أنا على Linux الآن ، أحاول بربط ثابت.
يجب أن يكون هذا شيئًا يركضه الكثير من الناس أو يغطون العديد من الكتب ، لكنني أشعر وكأنني غامم أعمى يجلس أمام هذه المشكلة. ومن المثير للاهتمام ، لا يوجد مثل هذا السؤال على ذلك أيضًا.
لا أعرف حتى ما إذا كان هذا يمكن أن ينجح ، أقل بكثير من كيفية القيام بذلك.
المحلول
عادةً ما تحتاج إلى إجبار برنامج التحويل البرمجي C ++ على إنشاء المكتبة مع رابط C للوظائف المصدرة.
يمكنك القيام بذلك عن طريق القيام بما يلي في رأسك:
#ifdef __cplusplus
extern "C" {
#endif
void func(void);
/* ... Other function defs go here ... */
#ifdef __cplusplus
}
#endif
عادةً ما يقوم الرابط بتنسيق الأسماء C ++ للوظائف ، بحيث لن يتمكن رابط C من العثور عليها. extern "C"
يجبرها على عدم القيام بذلك. تحتاج إلى لفه في #ifdef
, ، لان extern "C"
غير صالح في C.
تحديث
كما يقول تشارلز سالفيا في تعليق أدناه ، تحتاج إلى التأكد من عدم وجود استثناءات في طريقها من خلال واجهتك ، لأن C ليس لديه طريقة للتعامل معها (على الأقل ليس طريقة مستقلة عن النظام الأساسي).
نصائح أخرى
إذا كانت مكتبة C ++ لا توفر واجهة C ، فلا يمكنك ذلك.
إذا كان الأمر كذلك ، استخدم واجهة C.
إذا كنت المؤلف ، استخدم extern "C"
خاصية. http://www.parashift.com/c++-faq-lite/mixing-c--cpp.html
شخصياً ، سأكتب ملف C ++ يصدر الوظائف التي تستخدم رابط C. وبعبارة أخرى ، اكتب ملزمة.
على Linux ، يمكنك الحصول على الاسم المشوهة لوظائف C ++ الخاصة بك مع الأمر
nm my-tiny-c++lib.a
اتصل بالوظيفة من C باسمها المشوش ، ولكن لا تتوقع أن تكون هذه الخدعة محمولة ...
تعديل: ثم عليك الارتباط باستخدام G ++ ، أو مع GCC -LSTDC ++
إنها مشكلة من نقطة الانتشار. يستخدم خارجي ج حول C ++ تريد الاتصال من C.
mangling و def-mangling لم يكن موحدًا أبدًا في C ++ ، لأنه كان يعتمد أيضًا على النظام الأساسي. والنتيجة هي أنه على الرغم من أنه يمكنك معرفة اسم طريقة طريقة C ++ من خلال النظر إلى إخراج الرابط ، فلا توجد طريقة محمولة لإيجاد اسم "حقيقي" قابل للربط لطريقة الوظيفة C ++.
يمكنك كتابة غلاف C حول أي مكتبة C ++ تحتوي على API C ++. يجب كتابة الغلاف في C ++.
يمكنك حتى استخدام فئات C ++ الخاصة بك. أنت تعلنهم بألوان كهيكل. سيقوم بعض المترجمين بتقديم تحذير إذا قمت بذلك ، لكن على الأرجح يمكنك إما تعطيل هذا التحذير أو تجاهله فقط.
يمكنك الآن إنشاء وظائف حرة لإنشاء مؤشر لمثل هذا الهيكل (وليس مثيلًا ، حيث لا ترى تعريفه الكامل) والتخلص من مثل هذا المؤشر وجميع أساليبه عن طريق أخذها كمعلمة.
لاحظ أنه إذا كان الفصل في مساحة اسم ، فلن تتمكن من القيام بذلك ، لذا قم بإنشاء بنيتك الخاصة التي تحتوي على هذا العضو واستخدام هذا "Wrapper" بدلاً من ذلك.
لجميع وظائف C الخاصة بك. في الرأس فقط ، ضع
#ifdef __cplusplus
extern "C" {
#endif
// all your functions
#ifdef __cplusplus
}
#endif
الغلاف النموذجي يشبه هذا:
---- class_a.hpp ----
#include "class_a_wrapper"
class A {
public:
int foo(double p);
double bar(int x, int y);
}
---- class_a_wrapper.h ----
#ifdef __cplusplus
extern "C" {
#endif
struct wrap_A;
int wrap_A_foo(struct wrap_A *obj, double p);
double wrap_A_bar(struct wrap_A *obj, int x, int y);
#ifdef __cplusplus
}
#endif
---- class_a_wrapper.cpp ----
#include "class_a.hpp"
int wrap_A_foo(struct wrap_A *obj, double p) {
return (static_cast<A*>obj)->foo(p);
}
double wrap_A_bar(struct wrap_A *obj, int x, int y) {
return (static_cast<A*>obj)->bar(x, y);
}