10

我想使用 LoadLibrary 开发一个插件系统。
我的问题是:我希望我的函数采用 aconst char*LoadLibrary采用LPCTSTR.
我有一个好主意(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;
}
4

4 回答 4

20

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

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

于 2011-03-06T03:17:32.130 回答
8

我建议您使用TCHARandLoadLibrary而不是手动使用charorwchar_tLoadLibraryAorLoadLibraryW来制作通用应用程序,包括UNICODEASCII字符。

所以你可以这样做:

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

我建议你阅读这篇文章LPCTSTR是一个const TCHAR*

为什么使用LoadLibrary代替LoadLibraryWor LoadLibraryA?在不创建两个不同程序的情况下同时支持UNICODEASCII,一个用于工作,char另一个用于wchar_t.

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

于 2011-03-06T03:38:57.677 回答
0

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

bool PluginLoader::Load(const wchar_t *path)

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

于 2011-03-06T03:39:39.990 回答
0

批准的方法LoadLibrary使用 a char const *,而是使用 a 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;
}

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

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

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

于 2011-03-06T03:39:41.763 回答