ماذا علي أن أفعل إذا مكتبتين توفير وظيفة بنفس الاسم توليد الصراع ؟

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

  •  21-08-2019
  •  | 
  •  

سؤال

ماذا علي أن أفعل إذا كان لدي اثنين من المكتبات التي توفر الوظائف مع ما يعادل الأسماء ؟

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

المحلول

  • إذا كنت السيطرة على واحد أو كلا من:تحرير واحدة لتغيير اسم ترجمة أو مكافئ ترى بن و غير معروف's الإجابات التي سوف تعمل دون الوصول إلى التعليمات البرمجية المصدر.
  • إذا كنت لا تحكم أي منهم يمكنك لف واحد منهم.وهذا هو تجميع آخر (مرتبطة بشكل ثابت!) المكتبة أن لا يفعل شيئا إلا إعادة تصدير جميع رموز الأصلي إلا المخالف واحدة ، والتي يتم التوصل إليها من خلال غلاف اسم بديل.ما المتاعب.
  • وأضاف في وقت لاحق: منذ qeek يقول إنه يتحدث عن المكتبات الديناميكية ، فإن الحلول المقترحة من قبل فيروتشيو و mouviciel هي على الأرجح أفضل.(يبدو أنني أعيش في منذ أيام عندما ثابت الربط الافتراضي.فإنه الألوان تفكيري.)

بالمناسبه التعليقات:من خلال "تصدير" أعني لجعل مرئية وحدات ربط المكتبة---ما يعادل extern الكلمة في الملف نطاق.كيف يتم التحكم هو نظام التشغيل رابط تعتمد.و هو شيء أنا دائما يجب أن ننظر.

نصائح أخرى

ومن الممكن إعادة تسمية الرموز في ملف الكائن باستخدام objcopy --redefine-sym old=new file (انظر رجل objcopy).

وبعد ذلك مجرد دعوة الوظائف باستخدام أسمائهم جديدة والارتباط مع ملف الكائن الجديد.

وتحت Windows، يمكنك استخدام فشل LoadLibrary () لتحميل واحد من هذه المكتبات في الذاكرة ثم استخدام GetProcAddress () للحصول على عنوان كل وظيفة تحتاج إلى استدعاء واستدعاء وظائف من خلال مؤشر دالة.

ومنها مثلا.

HMODULE lib = LoadLibrary("foo.dll");
void *p = GetProcAddress(lib, "bar");
// cast p to the approriate function pointer type (fp) and call it
(*fp)(arg1, arg2...);
FreeLibrary(lib);

وسيحصل على عنوان من شريط وظيفة وردت أسماؤهم في foo.dll والذي يطلق عليه.

وأنا أعلم أنظمة يونكس تدعم وظائف مماثلة، ولكن لا يمكنني التفكير في أسمائهم.

هنا هو الفكر.فتح واحد من المخالف المكتبات في محرر عرافة و تغيير كافة تواجدات المخالف السلاسل إلى شيء آخر.ثم يجب أن تكون قادرا على استخدام أسماء جديدة في كل المكالمات في المستقبل.

تحديث: لقد فعلت ذلك على هذا ويبدو أن العمل. بالطبع, لم يتم اختبار هذا جيدا - قد يكون هناك أكثر من وسيلة جيدة حقا ضربة الخاص بك الساق مع hexedit بندقية.

ويجب عدم استخدامها معا. إذا كنت أتذكر بشكل صحيح، يصدر رابط خطأ في مثل هذه الحالة.

وأنا لم يحاول، ولكن قد يكون حلا مع dlopen()، dlsym() وdlclose() التي تسمح لك للتعامل مع المكتبات الديناميكية برمجيا. إذا كنت لا تحتاج وظائف اثنين في نفس الوقت، هل يمكن أن فتح أول مكتبة، استخدم الدالة الأولى وإغلاق المكتبة الأولى قبل استخدام المكتبة الثانية / وظيفة.

وعلى افتراض أن استخدام لينكس تحتاج أولا إلى إضافة

#include <dlfcn.h>

وتقوم بتعريف متغير مؤشر دالة في سياقها الصحيح، على سبيل المثال،

int (*alternative_server_init)(int, char **, char **);

ومثل ذكر فيروتشيو في https://stackoverflow.com/a/678453/1635364 ، تحميل صراحة المكتبة التي تريد استخدامها من خلال تنفيذ (اختيار الأعلام المفضلة لديك)

void* dlhandle;
void* sym;

dlhandle = dlopen("/home/jdoe/src/libwhatnot.so.10", RTLD_NOW|RTLD_LOCAL);

وقراءة عنوان الدالة التي تريد الاتصال بها في وقت لاحق

sym = dlsym(dlhandle, "conflicting_server_init");

وتعيين ويلقي على النحو التالي

alternative_server_init = (int (*)(int, char**, char**))sym;

واتصل بطريقة مماثلة من الأصل. وأخيرا، من خلال تنفيذ تفريغ

dlclose(dlhandle);

وهذه المشكلة هي السبب ج ++ لديها مساحات. ليس هناك في الواقع حل كبير في ج لمدة 2 ليبس طرف ثالث لها نفس الاسم.

إذا انها كائن حيوي، قد تكون قادرة على تحميل صراحة الكائنات المشتركة (فشل LoadLibrary / dlopen / الخ) والذي يطلق عليه بهذه الطريقة. بالتناوب، إذا كنت لا تحتاج إلى كل يبس في نفس الوقت في نفس الرمز، يمكنك ربما تفعل شيئا مع ربط ثابت (إذا كان لديك .LIB / ملفات .A).

وأي من هذه الحلول تنطبق على جميع المشاريع، بطبيعة الحال.

واحلف؟ بقدر ما أنا على علم، ليس هناك الكثير يمكنك القيام به إذا كان لديك اثنين من المكتبات التي تعرض نقطة الارتباط الذي يحمل نفس الاسم وتحتاج إلى ربط ضد كل من.

إذا كان لديك .o ملفات هناك إجابة جيدة هنا: https://stackoverflow.com/a/6940389/4705766

موجز:

  1. objcopy --prefix-symbols=pre_string test.o لإعادة تسمية الرموز .o ملف

أو

  1. objcopy --redefine-sym old_str=new_str test.o لإعادة تسمية محددة الرمز .o ملف.

ويجب عليك أن تكتب مكتبة التفاف حول واحد منهم. مكتبة المجمع الخاص بك ينبغي أن يعرض حرف مع أسماء فريدة من نوعها، وليس فضح رموز أسماء غير فريدة من نوعها.

والخيار الآخر الخاص بك هو لإعادة تسمية اسم الدالة في ملف الرأس، وإعادة تسمية الرمز في أرشيف الكائن مكتبة.

وفي كلتا الحالتين، لاستخدام كل من، انها ستعمل يكون العمل المأجور.

السؤال يقترب من العقد القديم ، ولكن هناك عمليات البحث الجديدة في كل وقت...

كما أجاب بالفعل ، objcopy مع-تعريف-sym العلم هو خيار جيد في لينكس.انظر ، على سبيل المثال ، https://linux.die.net/man/1/objcopy عن وثائق كاملة.هو عالي الكعب قليلا لأنك أساسا نسخ مكتبة كاملة في حين جعل التغييرات و كل تحديث يتطلب هذا العمل أن تتكرر.ولكن على الأقل يجب أن تعمل.

ويندوز بشكل حيوي تحميل المكتبة هو حل دائم مثل dlopen البديلة في لينكس سيكون.ومع ذلك كل dlopen() و LoadLibrary() إضافة المزيد من التعليمات البرمجية التي يمكن تجنبها إذا المسألة الوحيدة هي أسماء مكررة.هنا Windows الحل هو أكثر أناقة من objcopy النهج:قل رابط هذه الرموز في مكتبة معروفة من قبل بعض اسم آخر و استخدام هذا الاسم.هناك عدد قليل من الخطوات للقيام بذلك.تحتاج إلى جعل الملف def و تقديم اسم الترجمة في الصادرات القسم.انظر https://msdn.microsoft.com/en-us/library/hyx1zcd3.aspx (VS2015 ، وسوف تحصل في نهاية المطاف استبدال الإصدارات الأحدث) أو http://www.digitalmars.com/ctg/ctgDefFiles.html (ربما أكثر الدائمة) الكامل في بناء الجملة تفاصيل ملف def.عملية اعداد ملف def واحدة من المكتبات ثم استخدام هذا الملف def لبناء ملف lib ثم الارتباط مع هذا الملف lib.(ويندوز DLLs lib الملفات فقط تستخدم لربط لا البرمجية.) انظر كيفية جعل .الملف lib عندما يكون .ملف dll و رأس الملف عملية بناء ملف lib.هنا الفرق الوحيد هو إضافة الأسماء المستعارة.

لكل من لينكس و ويندوز, إعادة تسمية وظائف في رؤوس المكتبة الأسماء التي يجري مستعارة.خيار آخر ينبغي أن العمل سيكون في ملفات مشيرا إلى أسماء جديدة ، #تعريف old_name new_name, #وتشمل رؤوس المكتبة التي الصادرات يجري مستعارة ، ثم #undef old_name في المتصل.إذا كان هناك الكثير من الملفات باستخدام المكتبة أسهل البديل هو جعل رأس أو رؤوس يلتف يحدد يشمل undefs ومن ثم استخدام هذا الرأس.

نأمل أن تكون هذه المعلومات مفيدة!

ولقد استعملت أبدا dlsym، dlopen، dlerror، dlclose، dlvsym، وما إلى ذلك، ولكن أنا أبحث في الصفحة رجل، ويعطي مثالا على فتح libm.so واستخراج وظيفة كوس. لا dlopen تذهب من خلال عملية البحث عن الاصطدامات؟ إذا لم يحدث ذلك، يمكن للOP فقط تحميل كلا مكتبات يدويا وتعيين أسماء جديدة إلى جميع وظائف توفر مكتبات له.

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