【问题标题】:LoadLibrary taking a LPCTSTRLoadLibrary 采用 LPCTSTR
【发布时间】:2011-07-09 16:02:04
【问题描述】:

我想使用 LoadLibrary 开发一个插件系统。
我的问题是:我希望我的函数采用const char*LoadLibrary 采用LPCTSTR
我有一个 bright 想法去做(LPCSTR)path,它一直给我一个未找到模块的错误。

当前代码如下。如果我取消注释 widepath = L.. 行,它工作正常。我已经阅读了使用 MFC 的解决方案,但我不想使用 MFC。

当前代码:

bool PluginLoader::Load(char *path)
{
    path = "Release\\ExamplePlugin.dll";
    LPCTSTR widepath = (LPCTSTR)path;
    //widepath = L"Release\\ExamplePlugin.dll";

    HMODULE handle = LoadLibrary(widepath);
    if (handle == 0)
    {
        printf("Path: %s\n",widepath );
        printf("Error code: %d\n", GetLastError());

        return false;
    }

    int (*load_callback)() = (int (*)()) GetProcAddress(handle, "_plugin_start@0");

    if (load_callback == 0)
    {
        return false;
    }

    return load_callback() == LOAD_SUCCESS;
}

【问题讨论】:

    标签: c++ windows dll loadlibrary


    【解决方案1】:

    使用 LoadLibraryA(),它需要一个 const char*。

    接受字符串的 Winapi 函数有两个版本,一个接受 Ansi 字符串的 A 版本和一个接受宽字符串的 W 版本。函数名称有一个宏,例如 LoadLibrary,它扩展为 A 或 W,具体取决于 UNICODE 是否为#defined。您正在使用有效的#define 编译程序,因此您获得了LoadLibraryW()。只需作弊并使用 LoadLibraryA()。

    【讨论】:

    • 这就是这个网站存在的原因,它涵盖了不直观的内容;-)
    【解决方案2】:

    我建议您使用 TCHARLoadLibrary 而不是手动使用 charwchar_tLoadLibraryALoadLibraryW 来制作通用应用程序,既适用于 UNICODEASCII 个字符。

    所以你可以这样做:

    TCHAR x[100] = TEXT("some text");

    我建议你阅读this articleLPCTSTRconst TCHAR*

    为什么使用LoadLibrary 而不是LoadLibraryWLoadLibraryA?在不创建两个不同程序的情况下同时支持 UNICODEASCII,一个使用 char,另一个使用 wchar_t

    另外,看看微软是怎么说的:Conventions for Function Prototypes

    【讨论】:

      【解决方案3】:

      如果您继续为参数使用char *,您将遇到文件名中使用了不寻常字符并且LoadLibrary 将失败的情况。将函数更改为使用 wchar_t,并在使用该函数时创建参数 const,因为您没有修改字符串。

      bool PluginLoader::Load(const wchar_t *path)
      

      我想你会发现 32 位 Windows 上的 LPCTSTR 是一个宏,当程序选项设置为 Unicode 时,它​​会扩展为 const wchar_t *

      【讨论】:

        【解决方案4】:

        LoadLibrary 的认可方法是使用char const *,而是使用TCHAR const *,并在所有文字上使用_T 宏:

        bool PluginLoader::Load(TCHAR const *path) {
        
            path = _T("Release\\ExamplePlugin.dll");
        
            HMODULE handle = LoadLibrary(path);
            if (handle == 0)
            {
                _tprintf(_T("Path: %s\n"),widepath );
                _tprintf(_T("Error code: %d\n"), GetLastError());
        
                return false;
            }
        
            int (*load_callback)() = (int (*)()) GetProcAddress(handle, _T("_plugin_start@0"));
        
            if (load_callback == 0)
            {    
                return false;
            }    
            return load_callback() == LOAD_SUCCESS;
        }
        

        这将在 _UNICODE/UNICODE 定义时自动使用 LoadLibraryW,在未定义时自动使用 LoadLibraryA。同样,_T 将在相同的基础上给出窄或宽字符串文字,因此它们都保持同步。

        一般更喜欢显式使用W 后缀函数,并在字符串文字上使用L 前缀。无论如何,Windows 几乎只在内部使用宽字符串,因此采用窄字符串文字的版本A-suffixed 主要是将其参数转换为宽字符串的小存根,然后调用宽字符串版本。直接使用宽字符串版本既省时又省内存。

        Windows 中的窄字符串支持最初主要是为了与早已失效的缺乏宽字符串支持的 Windows 95/98/SE/Me 系列兼容。这些已经消失了很长一段时间,所以现在使用狭义文字的唯一原因是因为这是你从一些外部来源获得的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-07-11
          • 2012-04-04
          • 2010-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-07
          相关资源
          最近更新 更多