تلقي خطأ "رمز غير محدد" عند تحميل المكتبة باستخدام dlopen

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

  •  20-08-2019
  •  | 
  •  

سؤال

أنا أكتب بعض التعليمات البرمجية التي تستخدم المكتبات المشتركة الديناميكية كملابس إضافية.

يشبه سطر الأوامر الخاص بي لبناء المكتبات المشتركة:

cc -shared -fPIC -o module.so -g -Wall module.c

ضمن الوحدة النمطية ، يمكنني الاتصال بالوظائف الموجودة في أي مكتبة مشتركة أخرى تم تحميلها داخل المنافسة الرئيسية.

ومع ذلك ، لا يمكنني الوصول إلى وظائف (تم تصديرها) التي يتم تنفيذها في نفسها (أحصل عليها undefined symbol الأخطاء).

مكالمتي إلى dlopen يشبه هذا:

void *handle = dlopen(plugin, RTLD_NOW);

هل يمكن لأي شخص أن ينصح كيف يمكن للوحدة النمطية إعادة الاتصال إلى بلدي القابل للتنفيذ ، دون الحاجة إلى وضع جميع وظائف الأداة المساعدة القابلة للتنفيذ في مكتبة مشتركة أخرى؟

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

المحلول 2

لقد وجدت الجواب بنفسي.

اضطررت لإضافة ملف --export-dynamic أعلام إلى خيارات الارتباط للمادة القابلة للتنفيذ.

عند إنشاء عملية تنفيذية مرتبطة ديناميكيًا ، أضف جميع الرموز إلى جدول الرمز الديناميكي. جدول الرمز الديناميكي هو مجموعة الرموز المرئية من الكائنات الديناميكية في وقت التشغيل.

إذا لم تستخدم هذا الخيار ، فإن جدول الرمز الديناميكي عادة ما يحتوي فقط على الرموز التي يتم الإشارة إليها بواسطة بعض الكائنات الديناميكية المذكورة في الرابط.

إذا كنت تستخدم "dlopen" لتحميل كائن ديناميكي يحتاج إلى الرجوع إلى الرموز المحددة بواسطة البرنامج ، بدلاً من بعض الكائن الديناميكي الآخر ، فربما تحتاج إلى استخدام هذا الخيار عند ربط البرنامج نفسه.

نصائح أخرى

الحل الصحيح هو إضافة -rdynamic إلى أمر الارتباط الخاص بـ Main Executable. سيؤدي هذا إلى إضافة خيار مناسب إلى ld (والتي ، عند استخدامها GNU ld, ، يحدث أن تكون --export-dynamic).

مضيفا --export-dynamic مباشرة غير صحيح من الناحية الفنية: إنه خيار رابط ، وبالتالي يجب إضافته كـ -Wl,--export-dynamic, ، أو -Wl,-E. هذا أيضا أقل محمولة من -rdynamic (الروابط الأخرى لديها ما يعادلها ، ولكن الخيار نفسه مختلف).

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

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);

أعتقد أن الحل أفضل. والسبب هو أنه يحل نفس المشكلة أيضًا إذا كنت

أ) يرتبط البرنامج (أو وحدة طرف trird) (وليس في وقت التشغيل) مقابل المكتبة المشتركة ، والتي يجب أن تكون الرموز في جدول ديناميكي ؛

ب) لا يمكن إعادة ترجمة تلك الوحدة مع علم -rdynamic.

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