[RISOLTO]Alternativa a QLibrary o a libtool

di il
4 risposte

[RISOLTO]Alternativa a QLibrary o a libtool

Ciao a tutti, ho fatto un porting in Windows XP di un programma scritto in C++ per Linux.
Per fare in fretta ho usato l'ambiente di programmazione Qt 4.8.2 per il compilatore MinGW 4.6.2
In tale programma scritto per Linux originariamente si fa uso della libreria libtool per caricare le librerie dinamiche.
Di seguito riporto il pezzo di codice interessato:

void Model::LoadControllerModule( const char *lib )
{
    printf( "[Ctrl \"%s\"]\n", lib );

    // Initialise libltdl.
    int errors = lt_dlinit();
    if (errors)
    {
      printf( "Libtool error: %s. Failed to init libtool. Quitting\n",
              lt_dlerror() ); // report the error from libtool
      puts( "libtool error #1" );
      fflush( stdout );
      exit(-1);
    }

    printf( "[STAGEPATH: %s]\n",  FileManager::stagePath().c_str());

    lt_dlsetsearchpath( FileManager::stagePath().c_str() );
    printf( "ltdl search path: %s\n", lt_dlgetsearchpath() );

    // PLUGIN_PATH now defined in config.h
    lt_dladdsearchdir( PLUGIN_PATH );
    printf( "ltdl search path: %s\n", lt_dlgetsearchpath() );

    lt_dlhandle handle = NULL;
  
    // the library name is the first word in the string
    char libname[256];
    sscanf( lib, "%s %*s", libname );

    printf( "libname: %s\n", libname );

    if(( handle = lt_dlopenext( libname ) ))
    {
        model_callback_t initfunc = (model_callback_t)lt_dlsym( handle, "Init" );
        if( initfunc  == NULL )
        {
            printf( "(Libtool error: %s.) Something is wrong with your plugin.\n",
                    lt_dlerror() ); // report the error from libtool
            puts( "libtool error #1" );
            fflush( stdout );
            exit(-1);
        }

        // pass complete string into initfunc
        AddCallback( CB_INIT, initfunc, new CtrlArgs(lib, World::ctrlargs) );
    }
    else
    {
        printf( "(Libtool error: %s.) Can't open your plugin.\n",
                lt_dlerror() ); // report the error from libtool
		
        PRINT_ERR1( "Failed to open \"%s\". Check that it can be found by searching the directories"
                    "in your STAGEPATH environment variable, or the current directory if STAGEPATH "
                    "is not set.]\n", libname );
            
        printf( "ctrl \"%s\" STAGEPATH \"%s\"\n", libname, PLUGIN_PATH );
            
        puts( "libtool error #2" );
        fflush( stdout );
        exit(-1);
    }
  
    fflush(stdout);
}
Come dicevo prima ho usato l'ambiente Qt per risolvere il problema impiegando la classe QLibrary
di seguito riporto il codice che sostituisce quello sopra riportato:

void Model::LoadControllerModule( const char *lib )
{
    printf( "Model::LoadControllerModule() - [Ctrl \"%s\"", lib );
    fflush(stdout);

    char libname[256];
    strcpy(libname, lib);
    printf( "\nModel::LoadControllerModule() - libname = %s\n", libname );
    QLibrary library(libname);
    model_callback_t initfunc = (model_callback_t)library.resolve("Init");
    printf( "]" );

    if(initfunc == 0)
    {
        // report the error from QLibrary
        printf("\nModel::LoadControllerModule() - QLibrary error(%s) \nSomething is wrong with your
                  plugin.\n", library.errorString().toStdString().c_str());
        printf("QLibrary error #1\n");

        return;
    }

    // pass complete string into initfunc
    AddCallback(CB_INIT, initfunc, new CtrlArgs(lib, World::ctrlargs));
}
Così facendo funziona benissimo.
Ora vorrei trovare una soluzione che non faccia uso delle Qt 4.8.2 ma che usi normale codice in MinGW 4.7.1 usando come IDE Code::Blocks 13.12.
Mi potete aiutare a tal proposito ?

4 Risposte

  • Re: [RISOLTO]Alternativa a QLibrary o a libtool

    Non ho capito bene ... quali librerie devi caricare dinamicamente?
  • Re: [RISOLTO]Alternativa a QLibrary o a libtool

    Se non vuoi la portabilita del codice in Windows esiste LoadLibrary.
  • Re: [RISOLTO]Alternativa a QLibrary o a libtool

    Grazie per l'attenzione oregon e skynet. Rispondo subito.
    Sto programmando su Windows XP ed uso Code::Blocks 13.12 per Windows che usa MinGW 4.7.1 come compilatore gcc/g++.
    Ho provato ad usare la libtool che ha la utility ltdl per caricare a run time le librerie dinamiche (dll) costruite con libtool. Il problema è che nel primo codice che ho riportato mi dice (quando avvio il mio programma compilato con successo) che ltdl non trova la dll (quella creata con libtool/ltdl).
    Allora ero passato ad usare l'ambiente Qt 4.8.2 perchè aveva la classe QLibrary che mi permetteva di caricare la dll senza problemi (questa volta però la dll creata è stata fatta usando l'ambiente Qt 4.8.2).
    Ora mi chiedevo se esiste un altro modo per effettuare il caricamento (come riportato nel codice) della dll usando questa volta la creazione delle dll con Code::Blocks sempre per Windows XP e con MinGW 4.7.1.
    La libreria dinamica (wander.a/la/dll) da caricare è una libreria dinamica da me creata con Code::Blocks.
    Se sapete di più sul uso di libtool per Windows usando MinGW mi potete dare un semplicissimo esempio sia di creazione dll che di main per caricarla in un programma principale a run time ?
  • Re: [RISOLTO]Alternativa a QLibrary o a libtool

    Ok, mi rispondo da solo. Sono riuscito a risolvere il mio problema usando, come consigliato da skynet, Load Library. Per completezza di questo post riporto il nuovo codice che risolve il mio problema:
    
    #include <windows.h>
    #include <stdio.h>
    ...
    void Model::LoadControllerModule( const char *lib )
    {
        typedef int (__cdecl *MYPROC) (Model*, CtrlArgs*);
    
        HINSTANCE hinstLib;
        MYPROC ProcAdd;
        BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
    
        // the library name is the first word in the string
        char libname[256];
        sscanf( lib, "%s %*s", libname );
        printf( "libname: %s\n", libname );
        hinstLib = LoadLibrary(TEXT(libname));
        if (hinstLib != NULL) {
            printf("\n------------------------------------------\n");
            printf("\nhinstLib risulta essere non NULL\n");
            printf("\n------------------------------------------\n");
    
            ProcAdd = (MYPROC) GetProcAddress(hinstLib, "Init");
            model_callback_t initfunc = (model_callback_t)ProcAdd;
            if(initfunc == 0)
            {
                // report the error from QLibrary
                //printf("\nModel::LoadControllerModule() - QLibrary error(%s) \nSomething is wrong 
                //           with your plugin.\n", library.errorString().toStdString().c_str());
                printf("LoadLibrary error #1\n");
    
                return;
            }
    
            if (NULL != ProcAdd) {
                fRunTimeLinkSuccess = TRUE;
    
                if (NULL != initfunc) {
                    // pass complete string into initfunc
                    AddCallback( CB_INIT, initfunc, new CtrlArgs(lib, World::ctrlargs) );
                }
                else {
                    printf("\n------------------------------------------\n");
                    printf("\nERRORE: initfunc risulta essere NULL\n");
                    printf("\n------------------------------------------\n");
                }
            }
            else {
                printf("\n------------------------------------------\n");
                printf("\nERRORE: hinstLib risulta essere NULL\n");
                printf("\n------------------------------------------\n");
            }
    
            // Nota: va inserita dove si vuole scaricare la libreria dll
            //       per liberare la memoria e permettere di caricare
            //       un'altra libreria dll
            //fFreeResult = FreeLibrary(hinstLib);
        }
        else {
            printf("\n------------------------------------------\n");
            printf("\nERRORE: ProcAdd risulta essere NULL\n");
            printf("\n------------------------------------------\n");
        }
        if (!fRunTimeLinkSuccess)
            printf("Problema nel caricare la dll\n");
    }
    
    Quindi ho rifatto la mia libreria che viene richiamata dal codice sopra riportato e tutto funziona alla perfezione.
    Ora apro un nuovo post per chiedere lumi su Libtool e ltdl, vi aspetto là.
Devi accedere o registrarti per scrivere nel forum
4 risposte