错误C2664:无法转换参数错误

error C2664: cannot convert argument error

本文关键字:错误 转换 参数 C2664      更新时间:2023-10-16

我在编译代码和构建时会遇到以下错误

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

请建议什么问题以及如何解决此问题

错误是自称的。您正在通过wchar_t缓冲区/指针,其中预期char*指针。它们不是兼容类型。请注意,所有错误消息都指出了API函数的A NSI版本。

请勿使用#undef UNICODE!(联合)定义UNICODE(和C RTL的_UNICODE)并不是代码的责任。调用编译器时要处理该项目的责任。

通过不确定的UNICODE手动,您强迫所有基于TCHAR的Win32 API宏(就像您正在呼叫的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;
}