C의 Linux Dlopen 시스템

Cui Linux Dlopen Siseutem



라이브러리 함수 dlopen()은 C 언어에서 매우 유용한 함수입니다. 이 함수는 새 라이브러리를 연 후 라이브러리를 메모리에 로드합니다. 우리는 일반적으로 컴파일 시간에 알려지지 않은 라이브러리 기호를 로드하는 데 사용합니다. Dlopen()은 우리 프로그램에서 사용되는 함수입니다. DL 라이브러리는 Dlfcn.h에 정의된 dlopen()을 구현합니다. dlopen 함수에는 라이브러리 파일 이름과 플래그라는 두 개의 매개변수가 필요합니다. 파일 이름은 동적 라이브러리로 라이브러리의 종속성을 바로 계산할지 여부를 정의합니다. dlopen()은 불투명한 값으로 간주되어야 하는 '핸들'을 반환하고 다른 DL 라이브러리 작업에서 이를 사용합니다. 로드 시도가 실패하면 dlopen()은 NULL을 반환합니다. 그러나 dlopen()은 동일한 라이브러리를 여러 번 로드하는 경우 동일한 파일 핸들을 반환합니다.

dlopen 함수를 사용하는 동안 컴파일러는 우리가 사용하는 유형과 프로토타입을 인식하지 못하기 때문에 잠재적인 오류를 검사하지 않습니다. 몇 가지 사소한 상황을 제외하고 표준 로딩을 위한 dlopen 함수의 배포는 이에 의해 승격되지 않는 것으로 보입니다. 그건 그렇고, 그것은 내성을 향상시키는 접근 방식입니다. 공유 모듈이 현재 다른 프로그램에서 사용 중인 경우 메모리 레이아웃 최적화는 특히 조건부 로드에 관심이 없습니다. 이전에 사용된 라이브러리가 로드될 때 메모리 풋프린트가 증가하지 않습니다. 컴파일러 모니터링을 피하는 것은 위험하고 좋은 버그 작성을 만듭니다. 또한 가능한 컴파일러 최적화가 부족합니다.

예 1:

이제 다음 예제를 고려하여 C 언어에서 dlopen 함수의 기능을 확인하십시오. 첫 번째 단계에서는 일부 C 표준 라이브러리를 로드합니다. 여기에서 dlopen 모드 인수를 구성하는 동안 매크로를 정의하는 데 사용되는 새 라이브러리 'dlfcn.h'를 로드합니다.







그런 다음 'gnu/lib-name.h' 프로그램 내부에 다른 라이브러리를 소개합니다. GNU libc에 포함된 공유 라이브러리 파일은 정의한 매크로에 따라 사용자 프로그램에서 찾습니다. GNU C 라이브러리는 GNU 및 GNU/Linux 운영 체제는 물론 기타 다양한 Linux 기반 시스템을 위한 기본 라이브러리를 제공합니다. 그 후, 우리는 주요 메소드 구현이 있습니다. 그 안에서 void 키워드로 포인터 객체 'handle'을 선언합니다. 데이터 유형이 double인 포인터 사인 함수를 선언합니다. 오류 처리를 위한 포인터 개체 'error'의 또 다른 선언이 있습니다.



그런 다음 'handle' 개체 내부에서 dlopen 함수를 호출합니다. dlopen은 LIBM_SO 및 'RTLD_LAZY'의 두 인수를 사용합니다. 여기서 'LIBM_SO'는 삼각함수와 같은 수학함수를 제공하는 라이브러리 파일의 이름이다. 이 공유 라이브러리는 사인 함수를 사용할 때 필요합니다. 'RTLD_LAZY'는 dlopen 함수를 호출하는 또 다른 인수입니다. 주어진 심볼이 처음으로 참조될 때, 재배치는 구현에 의해 결정된 시간에 수행되어야 합니다.



프로세스가 실행 가능한 개체 파일의 모든 기호를 참조하지 않을 수 있으므로 RTLD LAZY를 지정하면 동적 기호 바인딩을 활성화하는 구현의 성능이 향상됩니다. 다음으로 핸들 객체가 dlopen 기능을 수행하는 데 실패할 때 오류 처리를 위한 if-else 조건이 있습니다. 오류를 지우기 위해 dlerror를 호출합니다.





dlerror() 함수는 사람이 읽을 수 있는 null 종료 문자열을 제공하며 마지막 dlerror 호출 이후 dlopen API 호출 중 하나에 대한 호출로 인해 발생한 최근 오류의 보고를 지정합니다. 그런 다음 '(*void**)(&sine)= dlsym(handle, sin)'과 같이 함수를 캐스팅합니다. 이상하게도 캐스팅은 컴파일러의 경고를 피하는 ISO C를 준수합니다. dlopen() 함수를 통해 액세스할 수 있는 동적 링크 모듈 내부에 지정된 기호의 경로를 가져오는 dlsym 함수를 사용합니다.

또한 dlerror()가 NULL이 아닐 때 발생하는 표준 오류에 대해 다시 if-else 연산을 수행한다. 그런 다음 계산할 사인 값을 지정하는 printf 문이 있습니다. 마지막 단계에서 dlopen()이 반환한 핸들에 대해 dlclose를 호출하여 공유 객체를 닫습니다.



#include
#포함
#포함
#include

정수
기본 ( 정수 인수 , ** argv )
{
무효의 * 핸들 ;
더블 ( * 그들의 것 ) ( 더블 ) ;
* 오류 ;

핸들 = 드로펜 ( LIBM_SO , RTLD_LAZY ) ;
만약에 ( ! 핸들 ) {
fprintf ( 표준 오류 , '%에스 \N ' , 오류 ( ) ) ;
출구 ( EXIT_FAILURE ) ;
}
오류 ( ) ;

* ( 무효의 ** ) ( & 그들의 것 ) = dlsym ( 핸들 , '없이' ) ;

만약에 ( ( 오류 = 오류 ( ) ) != 없는 ) {
fprintf ( 표준 오류 , '%에스 \N ' , 오류 ) ;
출구 ( EXIT_FAILURE ) ;
}

인쇄 ( '%에프 \N ' , ( * 그들의 것 ) ( 4.0 ) ) ;
닫기 ( 핸들 ) ;
출구 ( EXIT_SUCCESS ) ;
}

C 컴파일 명령과 함께 -ldl 옵션을 사용하는 이유는 이것이 dlopen 연결 인터페이스용 라이브러리이고 필수이기 때문입니다. dlopen 파일이 실행되면 이전에 주어진 값의 sine 값을 표시한다.

예 2:

이제 dlopen 함수를 사용하는 또 다른 예를 들어보겠습니다. dlopen 코드 구현에 필요한 모든 C 라이브러리와 함께 프로그램을 로드합니다. 그런 다음 main 메소드 내에서 프로그램을 시작합니다. 여기에서 변수 'src'의 선언으로 문자열을 정의합니다. 그런 다음 포인터 변수 'strlen', 'handle' 및 'error'를 선언합니다.

다음으로 핸들 변수를 호출하고 dlopen 함수를 배포합니다. dlopen 함수는 문자열 처리 함수를 위한 공유 라이브러리 'libstr.so'와 이전 예제에서 이미 설명한 플래그 'RTLD_LAZY'를 입력합니다. dlopen 함수에 의해 생성된 오류를 지우기 위해 'error' 변수 내에서 dlerror 함수를 호출합니다. if-else는 오류를 검사하는 데 사용됩니다.

그런 다음 dlsym 함수를 사용하여 strlen 함수의 주소를 얻고 이 작업을 수행하는 동안 오류를 확인합니다. 그런 다음 printf 함수를 사용하여 strnlen 함수를 호출하여 주어진 문자열의 길이를 반환합니다. 결국 dlclose 함수로 공유 라이브러리를 닫습니다.

#include
#포함
#포함
#include
정수 기본 ( 무효의 )
{
* src = '안녕 리눅스' ;
정수 ( * 스트렌 ) ( 상수 * ) ;
무효의 * 핸들 ;
* 오류 ;


핸들 = 드로펜 ( './libstr.so' , RTLD_LAZY ) ;
오류 = 오류 ( ) ;
만약에 ( ! 핸들 || 오류 != 없는 ) { 인쇄 ( '라이브러리 로드 시도 실패! \N %에스 \N ' , 오류 ) ;
반품 - 1 ; }

스트렌 = dlsym ( 핸들 , '스트렌' ) ;
오류 = 오류 ( ) ;
만약에 ( ! 스트렌 || 오류 == 없는 ) { 인쇄 ( '%에스 \N ' , 오류 ) ; 반품 - 1 ; }

인쇄 ( '문자열 길이:%d \N ' , 스트렌 ( src ) ) ;
닫기 ( 핸들 ) ;
반품 0 ;
}

주어진 프로그램을 실행하기 위해 다음 명령을 사용합니다. 여기서 -lstr 플래그는 문자열 길이 함수에 사용되고 ldl은 dlopen 라이브러리 파일에 사용됩니다. 컴파일된 프로그램은 쉘에 표시된 대로 문자열의 길이를 제공합니다.

결론

이 기사에서는 C 언어의 dlopen 기능에 대한 정보를 제공합니다. dlopen 함수에 대한 간략한 소개가 있습니다. 그런 다음 두 가지 예를 구현했습니다. 함수는 열린 라이브러리를 정의하는 식별자를 반환합니다. 열린 라이브러리 내부의 함수 주소는 이 식별자와 dlsym 함수를 사용하여 결정됩니다. dlopen을 사용하여 이미 열린 라이브러리 내의 함수 주소는 dlsym 함수를 사용하여 찾을 수 있습니다.