2011-03-06 17 views
5

Desidero sviluppare un sistema di plugin utilizzando LoadLibrary.
Il mio problema è: voglio che la mia funzione prenda un const char* e LoadLibrary prende uno LPCTSTR.
Ho avuto l'idea brillante da fare (LPCSTR)path che continuava a darmi un errore di modulo non trovato.

Il codice attuale è di seguito. Se disattivi la riga widepath = L.., funziona correttamente. Ho letto le soluzioni usando MFC ma non vorrei usare MFC.LoadLibrary taking a LPCTSTR

codice attuale:

bool PluginLoader::Load(char *path) 
{ 
    path = "Release\\ExamplePlugin.dll"; 
    LPCTSTR widepath = (LPCTSTR)path; 
    //widepath = L"Release\\ExamplePlugin.dll"; 

    HMODULE handle = LoadLibrary(widepath); 
    if (handle == 0) 
    { 
     printf("Path: %s\n",widepath); 
     printf("Error code: %d\n", GetLastError()); 

     return false; 
    } 

    int (*load_callback)() = (int (*)()) GetProcAddress(handle, "[email protected]"); 

    if (load_callback == 0) 
    { 
     return false; 
    } 

    return load_callback() == LOAD_SUCCESS; 
} 

risposta

12

Usa LoadLibraryA(), ci vuole un const char *.

Le funzioni di Winapi che accettano stringhe esistono in due versioni, una versione A che accetta stringhe Ansi e una versione W che accetta stringhe larghe. C'è una macro per il nome della funzione, come LoadLibrary, che si espande in A o W, a seconda che UNICODE sia #definito. Stai compilando il tuo programma con quel #define in effetti, quindi ottieni LoadLibraryW(). Semplicemente imbroglia e usa LoadLibraryA().

+0

Gah. grazie, mi sento ritardato ma a mia difesa, aggiungere un A non è così intuitivo. – Ben

+3

Ecco perché questo sito web esiste, copre l'intuitivo ;-) –

6

vi consiglio di utilizzare TCHAR e LoadLibrary invece di utilizzare manualmente char o wchar_t e LoadLibraryA o LoadLibraryW di presentare una domanda generica, sia per UNICODE e ASCII caratteri.

Così si potrebbe fare:

TCHAR x[100] = TEXT("some text");

vi consiglio di leggere this article. LPCTSTR è un const TCHAR*.

Perché utilizzare LoadLibrary anziché LoadLibraryW o LoadLibraryA? Per supportare sia UNICODE e ASCII senza creare due programmi diversi, uno per lavorare con char e l'altro con wchar_t.

Inoltre, dare un'occhiata a quello che dice Microsoft a questo proposito: Conventions for Function Prototypes

0

Se si continua ad usare un char * per il parametro, si incorrerà in casi in cui un personaggio singolare è usato nel nome del file e il LoadLibrary avrà esito negativo. Cambia la funzione per usare wchar_t invece, e mentre ci sei, imposta il parametro const poiché non stai modificando la stringa.

bool PluginLoader::Load(const wchar_t *path) 

Penso che troverete che LPCTSTR su Windows a 32 bit è una macro che si espande per const wchar_t * quando le opzioni del programma sono impostati su Unicode.

1

Il metodo approvato con LoadLibrary è quello di non utilizzare un char const *, ma invece utilizzare un TCHAR const *, e utilizzare la macro _T su tutti i letterali:

bool PluginLoader::Load(TCHAR const *path) { 

    path = _T("Release\\ExamplePlugin.dll"); 

    HMODULE handle = LoadLibrary(path); 
    if (handle == 0) 
    { 
     _tprintf(_T("Path: %s\n"),widepath); 
     _tprintf(_T("Error code: %d\n"), GetLastError()); 

     return false; 
    } 

    int (*load_callback)() = (int (*)()) GetProcAddress(handle, _T("[email protected]")); 

    if (load_callback == 0) 
    {  
     return false; 
    }  
    return load_callback() == LOAD_SUCCESS; 
} 

Questo userà automaticamente LoadLibraryW quando _UNICODE/UNICODE sono definito, e LoadLibraryA quando non lo sono. Allo stesso modo, _T darà letterali stringa stretti o larghi sulla stessa base, quindi tutto rimane sincronizzato.

ho generalmente preferiscono utilizzare le funzioni W suffisso in modo esplicito, e utilizzare il prefisso L sulle stringhe letterali. Windows funziona quasi esclusivamente internamente con stringhe larghe, quindi la versione A -suite con suffisso che accettano stringhe stringhe strette sono per lo più piccoli stub che convertono i loro argomenti in stringhe larghe, quindi chiamano la versione a stringa larga. L'utilizzo della versione a stringa larga consente di risparmiare tempo e memoria.

Il ristretto supporto per le stringhe di Windows era originariamente previsto principalmente per la compatibilità con la defunta linea Windows 95/98/SE/Me che mancava di un ampio supporto per le stringhe. Quelli sono spariti da un po 'di tempo, quindi l'unica ragione per usare letterali stretti ora è perché è quello che ti viene fornito da qualche fonte esterna.

Problemi correlati