web-dev-qa-db-ja.com

C ++でstd :: wstringをLPCTSTRに変換する方法は?

wstring形式のWindowsレジストリキー値があります。次に、このコードに渡します(最初の引数-javaw.exeへのパス):

std::wstring somePath(L"....\\bin\\javaw.exe");

    if (!CreateProcess("C:\\Program Files\\Java\\jre7\\bin\\javaw.exe", <--- here should be LPCTSTR, but I have a somePath in wstring format..
            cmdline, // Command line.
            NULL, // Process handle not inheritable.
            NULL, // Thread handle not inheritable.
            0, // Set handle inheritance to FALSE.
            CREATE_NO_WINDOW, // ON Vista/WIN7, THIS CREATES NO WINDOW
            NULL, // Use parent's environment block.
            NULL, // Use parent's starting directory.
            &si, // Pointer to STARTUPINFO structure.
            &pi)) // Pointer to PROCESS_INFORMATION structure.
    {
        printf("CreateProcess failed\n");
        return 0;
    }

どうやってやるの?

18

単にc_str の方程式 std::w/string

こちらをご覧ください:

http://www.cplusplus.com/reference/string/string/c_str/

std::wstring somePath(L"....\\bin\\javaw.exe");

    if (!CreateProcess(somePath.c_str(),
            cmdline, // Command line.
            NULL, // Process handle not inheritable.
            NULL, // Thread handle not inheritable.
            0, // Set handle inheritance to FALSE.
            CREATE_NO_WINDOW, // ON Vista/WIN7, THIS CREATES NO WINDOW
            NULL, // Use parent's environment block.
            NULL, // Use parent's starting directory.
            &si, // Pointer to STARTUPINFO structure.
            &pi)) // Pointer to PROCESS_INFORMATION structure.
    {
        printf("CreateProcess failed\n");
        return 0;
    }
24
paulm

LPCTSTRは古い遺物です。マルチバイト文字列を使用している場合はchar*、Unicodeを使用している場合はwchar_t*を定義するハイブリッドtypedefです。 Visual Studioでは、これは[キャラクターセット]の下の一般的なプロジェクトの設定で変更できます。

Unicodeを使用している場合:

std::wstring somePath(L"....\\bin\\javaw.exe");
LPCTSTR str = somePath.c_str();                 // i.e. std::wstring to wchar_t*

マルチバイトを使用している場合、このヘルパーを使用します。

// wide char to multi byte:
std::string ws2s(const std::wstring& wstr)
{
    int size_needed = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), 0, 0, 0, 0); 
    std::string strTo(size_needed, 0);
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), &strTo[0], size_needed, 0, 0); 
    return strTo;
}

つまり、マルチバイト文字列を含むstd::wstringからstd::stringへ、そしてchar*へ:

LPCTSTR str = ws2s(somePath).c_str();
9
LihO

Paulmが言及したように、少し修正してCreateProcessWを使用することに最終的に決めました-値をキャストする必要があります(そうしないとエラーが発生します)。

STARTUPINFOW si;
    memset(&si, 0, sizeof (STARTUPINFOW));
    si.cb = sizeof (STARTUPINFOW);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = FALSE;

    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof (PROCESS_INFORMATION));

    std::wstring cmdline(L" -jar install.jar");

    if (!CreateProcessW((LPCWSTR)strKeyValue.c_str(),
            (LPWSTR)cmdline.c_str(), // Command line.
            NULL, // Process handle not inheritable.
            NULL, // Thread handle not inheritable.
            0, // Set handle inheritance to FALSE.
            CREATE_NO_WINDOW, // ON Vista/WIN7, THIS CREATES NO WINDOW
            NULL, // Use parent's environment block.
            NULL, // Use parent's starting directory.
            &si, // Pointer to STARTUPINFO structure.
            &pi)) // Pointer to PROCESS_INFORMATION structure.
    {
        printf("CreateProcess failed\n");
        return 0;
    }
0

StdlibクラスからTCHARsと対話する際の最も安全な方法は、_std::basic_string<TCHAR>_を使用し、TEXT()マクロで生の文字列を囲むことです(TCHARは狭くも広くもできるためプロジェクトの設定に応じて)。

_std::basic_string<TCHAR> somePath(TEXT("....\\bin\\javaw.exe"));
_

これを行うスタイルコンテストには勝てないため、別の正しい方法は、WinAPI関数のナローバージョンまたはワイドバージョンを明示的に使用することです。例えば。その特定の場合:

  • _std::string_でCreateProcessAを使用(_char*_のtypedefであるLPCSTRを使用)
  • _std::u16string_または_std::wstring_でCreateProcessWを使用します(Windowsでは16ビットである_wchar_t*_のtypedefであるLPCWSTRを使用します)

C++ 17では、次のことができます。

_std::filesystem::path app = "my/path/myprogram.exe";
std::string commandcall = app.filename.string() + " -myAwesomeParams";
// define si, pi
CreateProcessA(
    const_cast<LPCSTR>(app.string().c_str()),
    const_cast<LPSTR>(commandcall.c_str()),
    nullptr, nullptr, false, CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr,
    &si, &pi)
_
0
Roi Danton