문제

런타임 에이 환경 변수를 어떻게 업데이트하여 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")
도움이 되었습니까?

해결책

Python과 같은 프로그램이 실행될 때까지 Dynamic Loader (Ld.so.1 또는 유사한 것)는 이미 LD_Library_Path를 읽었으며 그 이후에는 변경 사항이 표시되지 않습니다. 따라서 Python 소프트웨어 자체가 ld_library_path를 평가하고이를 사용하여 라이브러리의 가능한 경로 이름을 작성하지 않는 한 dlopen() 또는 사용하기에 동등한 함수는 스크립트에서 변수를 설정하는 데 영향을 미치지 않습니다.

당신이 그것이 작동하지 않는다고 말하면, Python이 가능한 모든 라이브러리 이름을 빌드하고 시도하지 않는다고 가정하는 것은 그럴듯 해 보입니다. 아마도 ld_library_path에만 의존 할 것입니다.

다른 팁

cdll 또는 cdll.loadlibrary ()에 대한 자격을 갖춘 경로를 제공하더라도 Python을 호출하기 전에 LD_LIBRARY_PATH를 설정해야 할 수도 있습니다. 공유 라이브러리가 다른 공유 라이브러리를 명시 적으로 지칭하고 그 라이브러리에 "rpath"가 설정되어 있지 않으면 해당 라이브러리의 경우 이미로드 된 경우에도 찾을 수 없습니다. 라이브러리의 rpath는 해당 라이브러리에서 필요한 다른 라이브러리를 검색하는 데 사용할 수있는 검색 경로를 지정합니다.

예를 들어, 나는 나에 의해 생산되지 않은 상호 의존적 인 제 3 자 라이브러리 세트가 있습니다. B. SO 참조 A.SO. A.를 미리로드하더라도 :

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

B.so는 단순히 'A.so'를 rpath없이 'A.so'라고 말하기 때문에 두 번째 하중에 오류가 발생합니다. 따라서 '/abs/path/to'를 포함시키기 위해 LD_LIBRARY_PATH를 미리 설정해야합니다.

ld_library_path를 설정하지 않으면 .SO 파일에서 rpath 항목을 수정합니다. Linux에는이 작업을 수행 한 두 가지 유틸리티가 있습니다. 패치 펠트. Chrath는 Ubuntu 저장소에서 구입할 수 있습니다. rpath를 변경할 수는 없습니다. 패치 엘프는 더 유연합니다.

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

그런 다음 런타임시 Python의 작업 디렉토리를 다음과 같이 변경할 수 있습니다.

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

이와 같이 로더는 또한 다른 동적 라이브러리를 찾습니다. 기타 브린

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top