2017-09-21 45 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()'應該是'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

錯誤是不言自明的。您正在傳遞wchar_t緩衝區/指針,其中char*指針是預期的。它們不是兼容的類型。請注意,所有錯誤消息都表示A正在調用API函數的NSI版本。

請勿使用#undef UNICODE!代碼的責任不在於定義UNICODE(和用於C RTL的_UNICODE)。在調用編譯器時處理該項目是項目的責任。

通過手動定義UNICODE,您將強制所有基於TCHAR的Win32 API宏(如您所調用的宏)映射到ANSI版本而不是Unicode版本。

如果要使用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); 
} 

話雖這麼說,不使用SetCurrentDirectory()影響,其中依賴的DLL中查找!正確的解決方案是使用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; 
    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. 

    // 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. 

    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; 
} 
相關問題