2017-09-21 43 views
-1

を変換することはできません私は私のコードをコンパイルしながら、次のエラーを取得し、構築していますが親切に間違っているものを示唆エラーC2664:引数エラー

Error 1 error C2664: 'DWORD GetCurrentDirectoryA(DWORD,LPSTR)' : cannot convert argument 2 from 'wchar_t [260]' to 'LPSTR' 
Error 2 error C2664: 'BOOL SetCurrentDirectoryA(LPCSTR)' : cannot convert argument 1 from 'wchar_t *' to 'LPCSTR' 
Error 3 error C2664: 'BOOL SetCurrentDirectoryA(LPCSTR)' : cannot convert argument 1 from 'wchar_t [260]' to 'LPCSTR' 
Error 4 error C2664: 'HMODULE GetModuleHandleA(LPCSTR)' : cannot convert argument 1 from 'const wchar_t [13]' to 'LPCSTR' 

私のCPPコード

// Copyright (c) 2011 The Chromium Authors. All rights reserved. 
// Use of this source code is governed by a BSD-style license that can be 
// found in the LICENSE file. 

#include "native_library.h" 

#undef UNICODE 

#include <windows.h> 


//#include "base/files/file_util.h" 
//#include "base/strings/stringprintf.h" 
//#include "base/strings/utf_string_conversions.h" 
//#include "base/threading/thread_restrictions.h" 

namespace base { 

typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name); 

namespace { 

NativeLibrary LoadNativeLibraryHelper(const std::string& library_path, 
             LoadLibraryFunction load_library_api, 
             NativeLibraryLoadError* error) { 
    // LoadLibrary() opens the file off disk. 
    //ThreadRestrictions::AssertIOAllowed(); 

    // Switch the current directory to the library directory as the library 
    // may have dependencies on DLLs in this directory. 
    bool restore_directory = false; 
    wchar_t current_directory[MAX_PATH]; 
    std::wstring lp = std::wstring(library_path.begin(), library_path.end()); 
    std::wstring plugin_path, plugin_value; 
    if (GetCurrentDirectory(MAX_PATH,current_directory)) 
    { 
    const wchar_t *res = wcsrchr(lp.c_str(), '\\'); 
    if (res) 
    { 
     plugin_path.assign(lp.c_str(),res); 
     plugin_value.assign(++res, wcsrchr(res,0)); 
    } 
    else 
     plugin_value = lp; 

    if (!plugin_path.empty()) 
    { 
     SetCurrentDirectory((wchar_t*)plugin_path.c_str()); 
     restore_directory = true; 
    } 
    } 

    HMODULE module = (*load_library_api)((wchar_t*)plugin_value.c_str()); 
    if (!module && error) { 
    // GetLastError() needs to be called immediately after |load_library_api|. 
    error->code = GetLastError(); 
    } 

    if (restore_directory) 
    SetCurrentDirectory(current_directory); 

    return module; 
} 

} // namespace 

std::string NativeLibraryLoadError::ToString() const 
{ 
    char buf[32]; 
    return int2char(code, buf); 
} 

// static 
NativeLibrary LoadNativeLibrary(const std::string& library_path, 
           NativeLibraryLoadError* error) { 
    return LoadNativeLibraryHelper(library_path, LoadLibraryW, error); 
} 

NativeLibrary LoadNativeLibraryDynamically(const std::string& library_path) { 
    typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name); 

    LoadLibraryFunction load_library; 
    load_library = reinterpret_cast<LoadLibraryFunction>(
     GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW")); 

    return LoadNativeLibraryHelper(library_path, load_library, NULL); 
} 

// static 
void UnloadNativeLibrary(NativeLibrary library) { 
    FreeLibrary(library); 
} 

// static 
void* GetFunctionPointerFromNativeLibrary(NativeLibrary library, 
              const char* name) { 
    return GetProcAddress(library, name); 
} 

// static 
//string16 GetNativeLibraryName(const string16& name) { 
// return name + ASCIIToUTF16(".dll"); 
//} 

} // namespace base 

成功したものではなく、どのように修正しますこの問題

+0

GetCurrentDirectoryの 'の第2引数()' 'LPSTR'とされていますが、' current_directory'は 'wchar_t '。 – Barmar

+4

なぜあなたは '#undef UNICODE'を持っていますか?これは、Windows APIの 'wstring'に正しい関数呼び出しを使用するために必要です。 – 1201ProgramAlarm

+0

間違っているのは、引数2を 'wchar_t [260]'から 'LPSTR'に変換できず、引数1を 'wchar_t *'から 'LPCSTR'に変換できないということです。さらに、引数1を 'wchar_t [260]'から 'LPCSTR'に変換することはできません。最後に、引数1を 'const wchar_t [13]'から 'LPCSTR'に変換することはできません。 –

答えて

0

エラーは自明です。 char*ポインターが必要な場合は、wchar_tバッファー/ポインターを渡しています。それらは互換性のある型ではありません。すべてのエラーメッセージは、A NSIバージョンのAPI関数が呼び出されていることを示しています。

#undef UNICODEを使用しないでください! UNICODE(およびC RTLの場合は_UNICODE)を定義することは、コードの責任ではありません。コンパイラを呼び出すときは、それを処理するのはプロジェクトの責任です。

手動でUNICODEを定義しないと、すべてのTCHARベースのWin32 APIマクロ(呼び出し元のものなど)がUnicodeバージョンではなくANSIバージョンにマップされます。

ANSI文字列を使用する場合は、A NSI関数を明示的に呼び出します。 Unicode文字列を使用する場合は、W ide関数を明示的に呼び出します。 TCHARの定義に依存することをやめてください。

代わりにこれを試してみてください:

NativeLibrary LoadNativeLibraryHelper(const std::string& library_path, 
             LoadLibraryFunction load_library_api, 
             NativeLibraryLoadError* error) { 
    // LoadLibrary() opens the file off disk. 
    //ThreadRestrictions::AssertIOAllowed(); 

    // Switch the current directory to the library directory as the library 
    // may have dependencies on DLLs in this directory. 
    WCHAR current_directory[MAX_PATH] = {0}; 
    bool restore_directory = false; 

    // THIS IS NOT THE PROPER WAY TO CONVERT A std::string TO A std::wstring! 
    // This only works properly for ASCII strings. You need to use 
    // MultiByteToWideChar() or std::wstring_convert or other equivalent 
    // to convert ANSI data to UNICODE data. Otherwise, library_path should 
    // be passed as a std::wstring to begin with... 
    // 
    std::wstring lp = std::wstring(library_path.begin(), library_path.end()); 

    std::wstring plugin_path, plugin_value;  
    const wchar_t *res = wcsrchr(lp.c_str(), L'\\'); 
    if (res) 
    { 
    plugin_path.assign(lp.c_str(), res); 
    plugin_value.assign(++res); 

    if (!plugin_path.empty()) 
    { 
     GetCurrentDirectoryW(MAX_PATH, current_directory); 
     restore_directory = SetCurrentDirectoryW(plugin_path.c_str()); 
    } 
    } 
    else 
    plugin_value = lp; 

    HMODULE module = (*load_library_api)(plugin_value.c_str()); 
    if (!module && error) { 
    // GetLastError() needs to be called immediately after |load_library_api|. 
    error->code = GetLastError(); 
    } 

    if (restore_directory) 
    SetCurrentDirectoryW(current_directory); 

    return module; 
} 

... 

NativeLibrary LoadNativeLibraryDynamically(const std::string& library_path) { 
    LoadLibraryFunction load_library; 
    load_library = reinterpret_cast<LoadLibraryFunction>(
     GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW")); 

    return LoadNativeLibraryHelper(library_path, load_library, NULL); 
} 

言われていること、依存DLLが検索される場所に影響するSetCurrentDirectory()を使用しないでください!正しい解決策は、代わりにSetDllDirectory()(XP SP1 +)またはAddDllDirectory()(Win8 +)を使用することです。

のみSetDllDirectory()を使用する:一つは実行時に実際に利用可能な方の使用

NativeLibrary LoadNativeLibraryHelper(const std::string& library_path, 
             LoadLibraryFunction load_library_api, 
             NativeLibraryLoadError* error) { 
    // LoadLibrary() opens the file off disk. 
    //ThreadRestrictions::AssertIOAllowed(); 

    // Include the library directory as the library may have dependencies on 
    // DLLs in this directory. 

    // THIS IS NOT THE PROPER WAY TO CONVERT A std::string TO A std::wstring! 
    // This only works properly for ASCII strings. You need to use 
    // MultiByteToWideChar() or std::wstring_convert or other equivalent 
    // to convert ANSI data to UNICODE data. Otherwise, library_path should 
    // be passed as a std::wstring to begin with... 
    // 
    std::wstring lp = std::wstring(library_path.begin(), library_path.end()); 

    std::wstring plugin_path, plugin_value; 
    DLL_DIRECTORY_COOKIE cookie = 0; 

    const wchar_t *res = wcsrchr(lp.c_str(), L'\\'); 
    if (res) 
    { 
    plugin_path.assign(lp.c_str(), res); 
    plugin_value.assign(++res); 

    if (!plugin_path.empty()) 
     cookie = AddDllDirectory(plugin_path.c_str()); 
    } 
    else 
    plugin_value = lp; 

    HMODULE module = (*load_library_api)(plugin_value.c_str()); 
    if (!module && error) { 
    // GetLastError() needs to be called immediately after |load_library_api|. 
    error->code = GetLastError(); 
    } 

    if (cookie) 
    RemoveDllDirectory(cookie); 

    return module; 
} 

NativeLibrary LoadNativeLibraryHelper(const std::string& library_path, 
             LoadLibraryFunction load_library_api, 
             NativeLibraryLoadError* error) { 
    // LoadLibrary() opens the file off disk. 
    //ThreadRestrictions::AssertIOAllowed(); 

    // Include the library directory as the library may have dependencies on 
    // DLLs in this directory. 

    // THIS IS NOT THE PROPER WAY TO CONVERT A std::string TO A std::wstring! 
    // This only works properly for ASCII strings. You need to use 
    // MultiByteToWideChar() or std::wstring_convert or other equivalent 
    // to convert ANSI data to UNICODE data. Otherwise, library_path should 
    // be passed as a std::wstring to begin with... 
    // 
    std::wstring lp = std::wstring(library_path.begin(), library_path.end()); 

    std::wstring plugin_path, plugin_value; 
    bool restore_old_order = false; 

    const wchar_t *res = wcsrchr(lp.c_str(), L'\\'); 
    if (res) 
    { 
    plugin_path.assign(lp.c_str(), res); 
    plugin_value.assign(++res); 

    if (!plugin_path.empty()) 
     restore_old_order = SetDllDirectoryW(plugin_path.c_str()); 
    } 
    else 
    plugin_value = lp; 

    HMODULE module = (*load_library_api)(plugin_value.c_str()); 
    if (!module && error) { 
    // GetLastError() needs to be called immediately after |load_library_api|. 
    error->code = GetLastError(); 
    } 

    if (restore_old_order) 
     SetDllDirectoryW(NULL); 

    return module; 
} 

AddDllDirectory()のみを使用

NativeLibrary LoadNativeLibraryHelper(const std::string& library_path, 
             LoadLibraryFunction load_library_api, 
             NativeLibraryLoadError* error) { 

    // LoadLibrary() opens the file off disk. 
    //ThreadRestrictions::AssertIOAllowed(); 

    // Include the library directory as the library may have dependencies on 
    // DLLs in this directory. 

    typedef BOOL (WINAPI* SetDllDirectoryFunction)(LPCWSTR lpPathName); 
    typedef PVOID DLL_DIRECTORY_COOKIE; 
    typedef DLL_DIRECTORY_COOKIE (WINAPI* AddDllDirectoryFunction)(PCWSTR NewDirectory); 
    typedef BOOL(WINAPI* RemoveDllDirectoryFunction)(DLL_DIRECTORY_COOKIE Cookie); 

    HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); 

    AddDllDirectoryFunction add_dll_directory; 
    add_dll_directory = reinterpret_cast<AddDllDirectoryFunction>(
    GetProcAddress(hKernel32, "AddDllDirectory")); 

    RemoveDllDirectoryFunction remove_dll_directory; 
    if (add_dll_directory) 
    { 
    remove_dll_directory = reinterpret_cast<RemoveDllDirectoryFunction>(
     GetProcAddress(hKernel32, "RemoveDllDirectory")); 
    } 
    else 
    remove_dll_directory = NULL; 

    SetDllDirectoryFunction set_dll_directory; 
    if (!(add_dll_directory && remove_dll_directory)) 
    { 
    set_dll_directory = reinterpret_cast<SetDllDirectoryFunction>(
     GetProcAddress(hKernel32, "SetDllDirectoryW")); 
    } 
    else 
    set_dll_directory = NULL; 

    // THIS IS NOT THE PROPER WAY TO CONVERT A std::string TO A std::wstring! 
    // This only works properly for ASCII strings. You need to use 
    // MultiByteToWideChar() or std::wstring_convert or other equivalent 
    // to convert ANSI data to UNICODE data. Otherwise, library_path should 
    // be passed as a std::wstring to begin with... 
    // 
    std::wstring lp = std::wstring(library_path.begin(), library_path.end()); 

    DLL_DIRECTORY_COOKIE cookie = 0; 
    bool restore_old_order = false; 
    std::wstring current_directory; 

    std::wstring plugin_path, plugin_value; 

    const wchar_t *res = wcsrchr(lp.c_str(), L'\\'); 
    if (res) 
    { 
    plugin_path.assign(lp.c_str(), res); 
    plugin_value.assign(++res); 

    if (!plugin_path.empty()) 
    { 
     if (add_dll_directory && remove_dll_directory) 
     cookie = (*add_dll_directory)(plugin_path.c_str()); 
     else if (set_dll_directory) 
     restore_old_order = (*set_dll_directory)(plugin_path.c_str()); 
     else 
     { 
     current_directory.resize(MAX_PATH); 
     GetCurrentDirectoryW(MAX_PATH, &current_directory[0]); 
     if (!SetCurrentDirectoryW(plugin_path.c_str())) 
      current_directory.clear(); 
     } 
    } 
    } 
    else 
    plugin_value = lp; 

    HMODULE module = (*load_library_api)(plugin_value.c_str()); 
    if (!module && error) { 
    // GetLastError() needs to be called immediately after |load_library_api|. 
    error->code = GetLastError(); 
    } 

    if (remove_dll_directory) 
    { 
    if (cookie) 
     (*remove_dll_directory)(cookie); 
    } 
    else if (set_dll_directory) 
    { 
    if (restore_old_order) 
     (*set_dll_directory)(NULL); 
    } 
    else if (!current_directory.empty()) 
    SetCurrentDirectoryW(current_directory.c_str()); 

    return module; 
}