LoadLibrary принимает LPCTSTR - PullRequest
       27

LoadLibrary принимает LPCTSTR

8 голосов
/ 06 марта 2011

Я хочу разработать систему плагинов с использованием LoadLibrary.Моя проблема: я хочу, чтобы моя функция принимала const char*, а LoadLibrary - LPCTSTR.У меня была яркая идея сделать (LPCSTR)path, которая продолжала давать мне ошибку "модуль не найден".Текущий код ниже.Если я раскомментирую строку widepath = L.., она будет работать нормально.Я читал решения с использованием MFC, но я бы не хотел использовать MFC.

Текущий код:

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, "_plugin_start@0");

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

    return load_callback() == LOAD_SUCCESS;
}

Ответы [ 4 ]

18 голосов
/ 06 марта 2011

Используйте LoadLibraryA (), он принимает константный символ *.

Функции Winapi, которые принимают строки, существуют в двух версиях: версия A, которая принимает строки Ansi, и версия W, которая принимает широкие строки. Существует макрос для имени функции, например LoadLibrary, который расширяется до A или W, в зависимости от того, является ли UNICODE #defined. Вы компилируете свою программу с этим #define, поэтому вы получаете LoadLibraryW (). Просто обманывайте и используйте LoadLibraryA ().

6 голосов
/ 06 марта 2011

Я предлагаю вам использовать TCHAR и LoadLibrary вместо использования вручную char или wchar_t и LoadLibraryA или LoadLibraryW для создания универсального приложения, как для UNICODE и ASCII символов.

Так что вы можете сделать:

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

Я предлагаю вам прочитать эту статью .LPCTSTR - это const TCHAR*.

Зачем использовать LoadLibrary вместо LoadLibraryW или LoadLibraryA?Для поддержки UNICODE и ASCII без создания двух разных программ, одна для работы с char, а другая с wchar_t.

Также посмотритеMicrosoft говорит об этом: Условные обозначения для функциональных прототипов

1 голос
/ 06 марта 2011

Утвержденный метод с LoadLibrary предназначен для , а не , используйте char const *, но вместо этого используйте TCHAR const * и используйте макрос _T для всех литералов:

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("_plugin_start@0"));

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

При этом будут автоматически использоваться LoadLibraryW, если определены _UNICODE / UNICODE, и LoadLibraryA, если они не определены. Аналогично, _T будет выдавать узкие или широкие строковые литералы на одной основе, поэтому все они будут синхронизированы.

I обычно предпочитают явно использовать суффиксные функции W и использовать префикс L для строковых литералов. В любом случае Windows работает почти исключительно с широкими строками, поэтому версии с поддержкой A, которые принимают узкие строковые литералы, в основном представляют собой небольшие заглушки, которые преобразуют свои аргументы в широкие строки, а затем вызывают версию с широкими строками. Использование широкоформатной версии напрямую экономит время и память.

Поддержка узких строк в Windows изначально была предусмотрена главным образом для совместимости с давно не существовавшей линией Windows 95/98 / SE / Me, в которой отсутствовала поддержка широких строк. Они давно исчезли, поэтому единственная причина использовать узкие литералы сейчас - это то, что вы получаете из какого-то внешнего источника.

0 голосов
/ 06 марта 2011

Если вы продолжите использовать char * для параметра, вы столкнетесь со случаями, когда в имени файла используется необычный символ, и LoadLibrary завершится ошибкой.Измените функцию, чтобы использовать вместо нее wchar_t, и пока вы ее используете, задайте параметр const, поскольку вы не изменяете строку.

bool PluginLoader::Load(const wchar_t *path)

Я думаю, вы найдете этот LPCTSTR на 32-Бит Windows - это макрос, который расширяется до const wchar_t *, когда для параметров программы установлено значение Unicode.

...