كيف يمكنني إلغاء تحميل DLL باستخدام ctypes في الثعبان ؟

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

  •  21-08-2019
  •  | 
  •  

سؤال

أنا باستخدام ctypes تحميل DLL في بيثون.هذا يعمل كبيرة.

الآن نود أن تكون قادرة على تحميل DLL هذا في وقت التشغيل.

واضحة النهج من شأنه أن يبدو أن يكون:1.إلغاء تحميل DLL 2.تحميل DLL

للأسف أنا لست متأكدا ما هي الطريقة الصحيحة لتفريغ DLL.

_ctypes.Freelibrary إلغاء متاح ، ولكن القطاع الخاص.

هل هناك طريقة أخرى لتفريغ DLL?

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

المحلول

يجب أن تكون قادرة على القيام بذلك عن طريق التخلص من الكائن

mydll = ctypes.CDLL('...')
del mydll
mydll = ctypes.CDLL('...')

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

Ctypes لا يبدو أن توفير وسيلة نظيفة الإفراج عن الموارد, أنها لا توفر سوى _handle مجال dlopen التعامل مع...

وبالتالي فإن الطريقة الوحيدة أراه حقا ، حقا غير نظيفة الطريقة, هو نظام بالاعتماد dlclose التعامل معها ، ولكن جدا جدا نجس ، وعلاوة على ذلك ctypes يبقى داخليا إشارات إلى هذا التعامل.حتى تفريغ يأخذ شيئا من شكل:

mydll = ctypes.CDLL('./mylib.so')
handle = mydll._handle
del mydll
while isLoaded('./mylib.so'):
    dlclose(handle)

إنه نجس أنا فقط التحقق من أنه يعمل باستخدام:

def isLoaded(lib):
   libp = os.path.abspath(lib)
   ret = os.system("lsof -p %d | grep %s > /dev/null" % (os.getpid(), libp))
   return (ret == 0)

def dlclose(handle)
   libdl = ctypes.CDLL("libdl.so")
   libdl.dlclose(handle)

نصائح أخرى

ومن المفيد أن تكون قادرة على تفريغ DLL بحيث يمكنك إعادة بناء DLL دون الحاجة إلى إعادة تشغيل الدورة إذا كنت تستخدم iPython أو تدفق عمل مماثل. العمل في ويندوز لقد حاولت فقط للعمل مع الأساليب المتعلقة النوافذ DLL.

REBUILD = True
if REBUILD:
  from subprocess import call
  call('g++ -c -DBUILDING_EXAMPLE_DLL test.cpp')
  call('g++ -shared -o test.dll test.o -Wl,--out-implib,test.a')

import ctypes
import numpy

# Simplest way to load the DLL
mydll = ctypes.cdll.LoadLibrary('test.dll')

# Call a function in the DLL
print mydll.test(10)

# Unload the DLL so that it can be rebuilt
libHandle = mydll._handle
del mydll
ctypes.windll.kernel32.FreeLibrary(libHandle)

وأنا لا أعرف الكثير من الأجزاء الداخلية لذلك أنا لست متأكدا حقا كيف نظيفة وهذا هو. أعتقد أن حذف mydll تطلق الموارد بيثون والدعوة FreeLibrary يقول النوافذ لتحريرها. كنت قد افترضت أن تحرير مع FreeLibary أولا قد تنتج مشاكل لذلك أنا حفظ نسخة من المقبض مكتبة وتحريرها في الترتيب هو موضح في المثال.

وأنا يستند هذا الأسلوب على تفريغ دلل حيث تحميل مقبض صراحة في خط الهجوم. اتفاقية التحميل ولكن لا يعمل كما هو نظيفة باسم "ctypes.cdll.LoadLibrary ( 'test.dll')" بهذه البساطة أنا اختار طريقة مبين.

إذا كنت تحتاج هذه الوظيفة، يمكن أن تكتب 2 دلس حيث الأحمال dll_A / مكتبة افرغت من dll_B. استخدام dll_A مثل الثعبان واجهة لوادر والعبور للوظائف في dll_B.

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