1

私は c++ が初めてで、助けが必要です。文字列を含むリソースのみの dll を作成しました。この dll を別のプロジェクトで使用して、保存されている文字列を読み取る必要があります。

文字列を読み取るために次の関数を作成しました。

LPTSTR GetResourceStr(HMODULE resContainer,int resourceID)
{
    //The stings that are stored in the dll are:
    //
    //ID            |Value|Caption
    //__________________________________________
    //IDS_STRING101 |101  |stringggg
    //IDS_STRING102 |102  |string 102
    //IDS_STRING103 |103  |string 103

    LPTSTR strBuffer = NULL;//is a (non-const) TCHAR string
    if(0!=resContainer){
      int copied=LoadString(resContainer,resourceID ,(LPTSTR)&strBuffer,0); 
    }
    return strBuffer;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE resContainer=LoadLibraryEx(L"ResourceDll.dll",NULL, LOAD_LIBRARY_AS_DATAFILE);

    LPTSTR msg = GetResourceStr(resContainer,101);
    std::wcout<<msg<<std::endl;
    //Expected output: stringggg
    //The output that i get: stringgggstring 102 string 103
    int i = 0;
    std::cin>>i;
    return 0;
}

期待される出力 - stringgggを取得するには、コードで何を変更する必要がありますか? なぜそれが起こっているのですか? LoadString はリソースから読み取った文字列にメモリを割り当てましたか、それとも文字列が既に格納されているメモリ内の場所へのポインタを取得しましたか? ご協力いただきありがとうございます!!

4

1 に答える 1

1

LoadString のドキュメントには次のように書かれています。

nBufferMax [in]

タイプ: int

バッファーのサイズ (文字単位)。文字列が指定された文字数よりも長い場合、文字列は切り捨てられ、null で終了します。このパラメーターが 0 の場合、lpBuffer はリソース自体への読み取り専用ポインターを受け取ります。

したがって、質問に直接答えるには、リソースが格納されているメモリへのポインターを取得するだけです。

ただし、文字列リソースは null で終了していないため (詳細については、こちらを参照してください)、その出力が得られるのはそのためです。LoadString の戻り値は、個々の文字列リソースの長さを示します。文字列を null で終了する必要がある場合は、次のように文字列を別のバッファーにコピーする必要があります。

WCHAR* pszString;
int iLength = ::LoadString(
    resContainer,
    resourceID,
    reinterpret_cast<LPWSTR>(&pszString),
    0
    );

WCHAR* pszString2 = new WCHAR[iLength + 1];
::StringCchCopyN(pszString2, iLength + 1, pszString, iLength);

または、3 番目のパラメーターとして (ポインターへのポインターではなく) バッファーへのポインターを指定して LoadString を呼び出し、4 番目のパラメーターとしてバッファーの長さを指定して、文字列リソースをバッファーにコピーし、null-それを終了します。欠点は、十分な長さを渡さないと文字列が切り捨てられることと、事前にリソースの長さを照会する方法がないことです。

于 2016-12-21T09:41:35.173 に答える