10

LoadLibraryを使ってプラグインシステムを開発したい。
私の問題は次のとおりです。関数にaを取り、をconst char*取りLoadLibraryたいLPCTSTR
私は、モジュールが見つからないというエラーを出し続け たという素晴らしいアイデアを思いつきました。 現在のコードは以下の通りです。行のコメントを外すと、正常に機能します。MFCを使用してソリューションを読みましたが、MFCを使用したくありません。(LPCSTR)path

widepath = L..

現在のコード:

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

4 に答える 4

20

LoadLibraryA()を使用すると、constchar*が必要になります。

文字列を受け取るWinapi関数には、Ansi文字列を受け取るAバージョンと幅の広い文字列を受け取るWバージョンの2つのバージョンがあります。UNICODEが#definedであるかどうかに応じて、AまたはWのいずれかに展開されるLoadLibraryのような関数名のマクロがあります。その#defineを有効にしてプログラムをコンパイルしているので、LoadLibraryW()を取得します。LoadLibraryA()をごまかして使用するだけです。

于 2011-03-06T03:17:32.130 に答える
8

UNICODE文字とASCII文字の両方に対して、手動で使用する代わりに、またはを使用TCHARして汎用アプリケーションを作成することをお勧めします。LoadLibrarycharwchar_tLoadLibraryALoadLibraryW

だからあなたはすることができます:

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

この記事を読むことをお勧めします。LPCTSTRですconst TCHAR*

またはLoadLibraryの代わりに使用する理由 2つの異なるプログラムを作成せずにUNICODEASCIIの両方をサポートするために、1つはで動作し、もう1つはで動作します。LoadLibraryWLoadLibraryAcharwchar_t

また、Microsoftがそれについて言っていることを見てください:関数プロトタイプの規則

于 2011-03-06T03:38:57.677 に答える
0

パラメータにaを引き続き使用するchar *と、ファイル名に異常な文字が使用され、LoadLibraryが失敗する場合があります。代わりにwchar_tを使用するように関数をconst変更し、文字列を変更していないので、そのときにパラメーターを作成します。

bool PluginLoader::Load(const wchar_t *path)

const wchar_t *32ビットWindowsのLPCTSTRは、プログラムオプションがUnicodeに設定されている場合に拡張されるマクロであることがわかると思います。

于 2011-03-06T03:39:39.990 に答える
0

で承認された方法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、同じ基準で狭い文字列リテラルまたは広い文字列リテラルを提供するため、すべての同期が維持されます。

私は通常W、接尾辞付きの関数を明示的に使用し、L文字列リテラルに接頭辞を使用することを好みます。Windowsは、とにかく内部的にワイド文字列でほぼ排他的に動作するため、Aナロー文字列リテラルを受け取るバージョンサフィックスバージョンは、ほとんどの場合、引数をワイド文字列に変換してからワイド文字列バージョンを呼び出す小さなスタブです。ワイドストリングバージョンを使用すると、時間とメモリの両方を直接節約できます。

Windowsでの狭い文字列のサポートは、元々、広い文字列のサポートがなかった、長い間使用されていなかったWindows 95/98 / SE/Meラインとの互換性のためにありました。それらはかなり前からなくなっているので、現在ナローリテラルを使用する唯一の理由は、それが外部ソースから供給されているためです。

于 2011-03-06T03:39:41.763 に答える