Come avrebbe una funzione di libreria caricata chiamare un simbolo nel ricorso principale?

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

  •  23-08-2019
  •  | 
  •  

Domanda

Quando si carica una libreria condivisa viene aperto tramite la funzione dlopen(), c'è un modo per farlo chiamare le funzioni nel programma principale?

È stato utile?

Soluzione

Codice di dlo.c (lib):

#include <stdio.h>

// function is defined in main program
void callb(void);

void test(void) {
    printf("here, in lib\n");
    callb();
}

Compila con

gcc -shared -olibdlo.so dlo.c

Ecco il codice del programma principale (copiato dalla pagina di manuale dlopen, e regolata):

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

void callb(void) {
    printf("here, i'm back\n");
}

int
main(int argc, char **argv)
{
    void *handle;
    void (*test)(void);
    char *error;

    handle = dlopen("libdlo.so", RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    dlerror();    /* Clear any existing error */

    *(void **) (&test) = dlsym(handle, "test");

    if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }

    (*test)();
    dlclose(handle);
    exit(EXIT_SUCCESS);
}

Costruire con

gcc -ldl -rdynamic main.c

Output:

[js@HOST2 dlopen]$ LD_LIBRARY_PATH=. ./a.out
here, in lib
here, i'm back
[js@HOST2 dlopen]$

L'opzione -rdynamic mette tutti i simboli nella tabella dei simboli dinamica (che è mappato in memoria), non solo i nomi dei simboli utilizzati. Per saperne di più su di esso qui . Naturalmente è possibile anche fornire puntatori a funzione (o una struttura di puntatori a funzione) che definiscono l'interfaccia tra la biblioteca e il programma principale. E 'in realtà il metodo quello che sceglierei probabilmente. Ho sentito da altre persone che non è così facile da fare -rdynamic in finestre, ed è anche farebbe per una comunicazione più pulito tra la libreria e il programma principale (che hai un controllo preciso su ciò che può essere chiamato e non), ma richiede anche più house-keeping.

Altri suggerimenti

Sì, se si fornisce la libreria un puntatore a tale funzione, sono sicuro che la biblioteca sarà in grado di eseguire / eseguire la funzione nel programma principale.

Ecco un esempio, non hanno compilato quindi attenzione;)

/* in main app */

/* define your function */

int do_it( char arg1, char arg2);

int do_it( char arg1, char arg2){
  /* do it! */
  return 1;
}

/* some where else in main app (init maybe?) provide the pointer */
 LIB_set_do_it(&do_it);
/** END MAIN CODE ***/

/* in LIBRARY */

int (*LIB_do_it_ptr)(char, char) = NULL;

void LIB_set_do_it( int (*do_it_ptr)(char, char) ){
    LIB_do_it_ptr = do_it_ptr;
}

int LIB_do_it(){
  char arg1, arg2;

  /* do something to the args 
  ...
  ... */

  return LIB_do_it_ptr( arg1, arg2);
}

La funzione dlopen(), come discusso da @ litb, viene fornita principalmente nei sistemi che utilizzano file oggetto formato ELF. E 'piuttosto potente e vi permetterà di controllare se i simboli a cui fa riferimento la libreria caricata possono essere soddisfatte dal programma principale, e in genere non lasciarli essere soddisfatti. Non tutti i sistemi di carico libreria condivisa sono flessibili - essere a conoscenza se si tratta di porting il codice

.

Il meccanismo di callback delineato da @hhafez funziona ora che il tiro in quel codice sono raddrizzato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top