Sistema Dlopen Linux em C

Sistema Dlopen Linux Em C



A função de biblioteca dlopen() é uma função muito útil na linguagem C. A função carrega a biblioteca na memória após abrir uma nova. Geralmente o usamos para carregar os símbolos da biblioteca que são desconhecidos no momento da compilação. Dlopen() é uma função que é usada em nossos programas. A biblioteca DL implementa dlopen(), definido em Dlfcn.h. Dois parâmetros são necessários para a função dlopen: o nome do arquivo de biblioteca e o sinalizador. O nome do arquivo é uma biblioteca dinâmica e define se as dependências da biblioteca são calculadas imediatamente. O dlopen() retorna um “handle” que deve ser considerado como um valor opaco e outras operações da biblioteca DL usam isso. Se a tentativa de carregamento não for bem-sucedida, dlopen() retornará NULL. Mas o dlopen() retorna o mesmo handle de arquivo se carregar a mesma biblioteca muitas vezes.

Ao utilizar a função dlopen, o compilador não examina possíveis erros, pois desconhece os tipos e protótipos que estamos usando. A implantação da função dlopen para carregamento padrão não parece ser promovida por ela, exceto em algumas situações menores. A propósito, é uma abordagem para melhorar a introspecção. Quando o módulo compartilhado está sendo utilizado por outro programa, a otimização do layout de memória não está particularmente interessada no carregamento condicional. O consumo de memória não aumenta quando uma biblioteca usada anteriormente é carregada. Evitar o monitoramento do compilador é perigoso e contribui para uma boa escrita de bugs. Além disso, não temos a possível otimização do compilador.

Exemplo 1:

Agora, considere o exemplo a seguir para ver a funcionalidade da função dlopen na linguagem C. Na primeira etapa, carregamos algumas bibliotecas padrão C. Aqui, carregamos a nova biblioteca “dlfcn.h” que é usada para definir as macros enquanto construímos o argumento do modo dlopen.







Em seguida, introduzimos outra biblioteca dentro do nosso programa “gnu/lib-name.h”. Os arquivos de biblioteca compartilhados incluídos no GNU libc são encontrados pelos programas do usuário de acordo com as macros que ele define. A GNU C Library oferece as bibliotecas fundamentais para os sistemas operacionais GNU e GNU/Linux, bem como uma ampla variedade de outros sistemas baseados em Linux. Depois disso, temos a implementação do método main. Dentro disso, declaramos o objeto ponteiro “handle” com a palavra-chave void. Declaramos uma função seno de ponteiro que tem o tipo de dados double. Há outra declaração do objeto ponteiro “erro” para tratamento de erros.



Depois disso, invocamos a função dlopen dentro do objeto “handle”. O dlopen recebe dois argumentos: LIBM_SO e “RTLD_LAZY”. Aqui, “LIBM_SO” é o nome do arquivo de biblioteca que fornece funções matemáticas como funções trigonométricas. Essa biblioteca compartilhada é necessária, pois usamos a função seno. O “RTLD_LAZY” é outro argumento que chama a função dlopen. Quando um determinado símbolo é referenciado pela primeira vez, as realocações devem ser realizadas em um momento determinado pela implementação.



Como um processo pode não fazer referência a todos os símbolos em um arquivo de objeto executável, especificar o RTLD LAZY deve melhorar o desempenho em implementações que permitem a vinculação dinâmica de símbolos. Em seguida, temos uma condição if-else para tratamento de erros quando o objeto handle falha ao executar a função dlopen. Chamamos o dlerror para limpar o erro.





A função dlerror() fornece uma string terminada em nulo que pode ser lida por humanos e especifica o relatório do erro recente causado por uma chamada para uma das chamadas da API dlopen desde a última chamada dlerror. Então, lançamos a função assim: “(*void**)(&sine)= dlsym(handle, sin)”. Como isso é estranho, a conversão está em conformidade com a ISO C, o que evita avisos do compilador. Empregamos a função dlsym que obtém o caminho de um símbolo que é especificado dentro de um módulo de link dinâmico que é acessível através de uma função dlopen().

Além disso, realizamos a operação if-else novamente para o erro padrão que é gerado quando dlerror() não é NULL. Então, temos uma instrução printf onde especificamos o valor do seno a ser calculado. Na última etapa, fechamos esse objeto compartilhado invocando o dlclose para o handle retornado pelo dlopen().



#include
#include
#include
#include

int
a Principal ( int argumento , Caracteres ** argv )
{
vazio * lidar com ;
em dobro ( * deles ) ( em dobro ) ;
Caracteres * erro ;

lidar com = cair ( LIBM_SO , RTLD_LAZY ) ;
E se ( ! lidar com ) {
fprintf ( stderr , '%s \n ' , erro ( ) ) ;
saída ( EXIT_FAILURE ) ;
}
erro ( ) ;

* ( vazio ** ) ( & deles ) = dlsym ( lidar com , 'sem' ) ;

E se ( ( erro = erro ( ) ) != NULO ) {
fprintf ( stderr , '%s \n ' , erro ) ;
saída ( EXIT_FAILURE ) ;
}

printf ( '%f \n ' , ( * deles ) ( 4,0 ) ) ;
dlclose ( lidar com ) ;
saída ( EXIT_SUCCESS ) ;
}

Usamos a opção -ldl com o comando de compilação C, pois esta é a biblioteca para a interface vinculada dlopen e é necessária. Quando a execução do arquivo dlopen é feita, ele exibe o valor do seno do valor dado anteriormente.

Exemplo 2:

Agora, tomamos outro exemplo de uso da função dlopen. Carregamos nosso programa com todas as bibliotecas C necessárias para a implementação do código dlopen. Em seguida, iniciamos nosso programa dentro do método main. Aqui, definimos a string com a declaração da variável “src”. Em seguida, declaramos as variáveis ​​de ponteiro “strlen”, “handle” e “error”.

Em seguida, chamamos a variável handle e implantamos a função dlopen. A função dlopen insere a biblioteca compartilhada “libstr.so” para funções de manipulação de strings e o sinalizador “RTLD_LAZY” que já foi demonstrado no exemplo anterior. Chamamos a função dlerror dentro da variável “error” para limpar o erro gerado pela função dlopen. O if-else é utilizado para examinar os erros.

Então, obtemos o endereço da função strlen usando a função dlsym e verificamos os erros ao fazer isso. Depois disso, usamos a função printf para chamar a função strnlen para retornar o comprimento da string fornecida. No final, fechamos a biblioteca compartilhada com a função dlclose.

#include
#include
#include
#include
int a Principal ( vazio )
{
Caracteres * src = 'Olá Linux' ;
int ( * forte ) ( const Caracteres * ) ;
vazio * lidar com ;
Caracteres * erro ;


lidar com = cair ( './libstr.so' , RTLD_LAZY ) ;
erro = erro ( ) ;
E se ( ! lidar com || erro != NULO ) { printf ( 'Falha na tentativa de carregamento da biblioteca! \n %s \n ' , erro ) ;
Retorna - 1 ; }

forte = dlsym ( lidar com , 'estrela' ) ;
erro = erro ( ) ;
E se ( ! forte || erro == NULO ) { printf ( '%s \n ' , erro ) ; Retorna - 1 ; }

printf ( 'O comprimento da string é:%d \n ' , forte ( src ) ) ;
dlclose ( lidar com ) ;
Retorna 0 ;
}

Usamos o seguinte comando para a execução do programa fornecido. Aqui, o sinalizador -lstr é usado para a função de comprimento de string e o ldl é usado para o arquivo de biblioteca dlopen. O programa compilado fornece o comprimento da string conforme mostrado no shell:

Conclusão

As informações são fornecidas sobre a função dlopen da linguagem C neste artigo. Temos uma breve introdução da função dlopen. Em seguida, implementamos dois exemplos. A função retorna um identificador que define a biblioteca aberta. Os endereços das funções dentro da biblioteca aberta são então determinados usando este identificador e a função dlsym. O endereço de uma função dentro de uma biblioteca que já foi aberta usando dlopen pode ser encontrado usando a função dlsym.