سؤال

وكيف تقوم بتحديث هذا متغير البيئة في وقت التشغيل بحيث ctypes يمكن تحميل مكتبة أينما؟ لقد حاولت ما يلي ولا يبدو للعمل.

from ctypes import *
os.environ['LD_LIBRARY_PATH'] = "/home/starlon/Projects/pyCFA635/lib"  
os.putenv('LD_LIBRARY_PATH', "/home/starlon/Projects/pyCFA635/lib")  
lib = CDLL("libevaluator.so")
هل كانت مفيدة؟

المحلول

وبحلول الوقت الذي برنامج مثل بايثون قيد التشغيل، محمل الحيوي (ld.so.1 أو شيئا من هذا القبيل) قد قرأ بالفعل LD_LIBRARY_PATH وسوف لا تلاحظ أي تغييرات بعد ذلك. لذلك، ما لم يكن البرنامج بيثون يقيم نفسه LD_LIBRARY_PATH ويستخدم لبناء اسم المسار المحتمل للمكتبة للdlopen() أو وظيفة أي ما يعادل استخدام، تعيين متغير في البرنامج النصي لن يكون لها تأثير.

وبالنظر إلى أن أقول لكم أنه لا يعمل، فإنه يبدو من المعقول أن نفترض أن بيثون لا تبني ومحاولة كل الأسماء مكتبة الممكنة؛ وربما يعتمد على LD_LIBRARY_PATH وحدها.

نصائح أخرى

وحتى إذا كنت تعطي مسار مؤهل بشكل كامل لCDLL أو cdll.LoadLibrary ()، قد لا تزال تحتاج إلى تعيين LD_LIBRARY_PATH قبل استدعاء بيثون. إذا المكتبة المشتركة قمت بتحميل صراحة يشير إلى مكتبة مشتركة أخرى ولا "rpath" تم تعيينها في. لذا لهذه المكتبة، ثم لن يتم العثور عليها، حتى لو تم تحميلها بالفعل. يحدد على rpath في المكتبة لديها مسار البحث لاستخدامها للبحث عن المكتبات الأخرى التي يحتاجها تلك المكتبة

وعلى سبيل المثال، لدي حالة وجود مجموعة من المكتبات طرف ثالث مترابطة لا تنتجها لي. b.so المراجع a.so. حتى لو كنت تحميل a.so مقدما:

ctypes.cdll.LoadLibrary('/abs/path/to/a.so')
ctypes.cdll.LoadLibrary('/abs/path/to/b.so')

وأحصل على خطأ على الحمل الثاني، لأن b.so يشير إلى ببساطة 'a.so، دون rpath، وذلك b.so لا يعرف أن في a.so. صحيحة لذلك لا بد لي من وضع LD_LIBRARY_PATH مقدما لتشمل '/ ABS / الطريق /.

لتجنب الاضطرار لتحديد LD_LIBRARY_PATH، تعديل إدخال rpath في ملفات لذا. على لينكس، هناك نوعان من المرافق وجدت أن قيام بذلك: chrpath، و patchelf . chrpath هو متاح من مستودعات أوبونتو. لا يمكن أن تغير rpath على ل. حتى أن لم يكن واحد. patchelf أكثر مرونة.

ويمكن أن تنتقل CDLL اسم مسار مؤهل بشكل كامل، وذلك على سبيل المثال أنا باستخدام التالية في واحدة من كتاباتي حيث. لذا هو في نفس الدليل النصي الثعبان.

import os
path = os.path.dirname(os.path.realpath(__file__))
dll = CDLL("%s/iface.so"%path)

في قضيتك ينبغي أن يكون كافيا ما يلي.

from ctypes import *
lib = CDLL("/home/starlon/Projects/pyCFA635/lib/libevaluator.so")

وتجميع ثنائي مع rpath قريب إلى دليل العمل الحالي مثل:

gcc -shared -o yourbinary.so yoursource.c otherbinary.so \
    -Wl,-rpath='.',-rpath='./another/relative/rpath' -fpic

وبعد ذلك، كنت قادرا على تغيير دليل العمل في بيثون في وقت التشغيل مع:

import os
os.chdir('/path/to/your/binaries')

ومثل هذا، يجد محمل أيضا المكتبات الديناميكية الأخرى مثل otherbinary.so

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