c++ - 在 C++ 中的不同项目文件中将参数)传递给函数)

标签 c++ c++11 visual-c++-2010

我只是对将参数传递给不同项目的 C++ 函数感到困惑。

我有两种不同的解决方案,一种是 DLL 项目,另一种是 Console 项目。在第一个项目中,我有一段代码如下:

class __declspec(dllexport) FormatLog
{
public:
    void __cdecl ParseFormat(LPCWSTR);
};

其余的代码在这里并不重要,而在第二个项目中我有包含以下代码的头文件:

class FormatImpl
{
public:
    typedef void (__cdecl * FORMAT) (LPCWSTR);
    HINSTANCE hModule;
    FORMAT Format;
    FormatImpl()
    {
        hModule = LoadLibrary(L"FormatLog.dll");
        if (hModule != NULL)
        {
            Format = (FORMAT) GetProcAddress(hModule, "?ParseFormat@FormatLog@@XXXXXXXX@X");
        }
    }
    ~FormatImpl()
    {
        if (hModule != NULL)
        {
            FreeLibrary(hModule);
        }
    }
};

当我使用以下代码从主函数调用它时:

int main(int argc, char* argv[])
{
    FormatImpl format;
    format.Format(L"%t %m %i %l");
    return 0;
}

参数在函数中无效void __cdecl ParseFormat(LPCWSTR format);作为<Bad Ptr>同时通过 Visual Studio 2010 检查。

我的问题是,如果我使用 GetProcAddressLoadLibrary要调用调用任何方法的 .dll 文件,我是否应该将除 int、double、long 等之外的任何参数传递给请求的方法是合法的?

最佳答案

您的代码中存在一个主要问题:ParseFormat 不是接受 LPWSTR 并返回 void 的函数,而是 FormatLog 类的实例方法>。不同之处在于,对于实例方法,您有一个隐藏的 this 参数。

如果您可以控制第一个项目,恕我直言,最简单的方法就是使用静态方法摆脱隐藏参数:

class __declspec(dllexport) FormatLog
{
public:
    static void __cdecl ParseFormat(LPCWSTR);
};

如果您无法控制第一个项目,FORMAT 的正确类型将是指向成员的指针。不幸的是,我一直找不到将 GetProcAddress 的结果转换为指向成员的指针的方法。希望众所周知,您可以简单地获取成员函数的地址并直接调用它,前提是您将隐藏的 this 添加为第一个参数。代码将变为:

class FormatImpl
{
public:
    typedef void (__cdecl *FORMAT) (FormatLog *l, LPCWSTR);
    HINSTANCE hModule;
    FORMAT Format;
    FormatImpl()
    {
        hModule = LoadLibrary(L"FormatLog.dll");
        if (hModule != NULL)
        {
            Format = (FORMAT) (void *) GetProcAddress(hModule,
                "?ParseFormat@FormatLog@@QAAXPB_W@Z");
        }
    }
    ...
}

(在 FormatLog.exp 中获取损坏的名称后),您将像这样使用它:

int main(int argc, char* argv[])
{
    FormatImpl format;
    FormatLog l;
    format.Format(&l, L"%t %m %i %l");
    return 0;
}

总之,我通常认为错位的名称应该是一个实现细节,如果我以后想通过 GetProcAddress< 手动导入它们,我只会从 DLL 中导出 extern "C" 函数.

所以我的建议是在第一个项目中添加:

extern "C" {
    __declspec(dllexport) void __cdecl doParseFormat(LPWSTR str) {
        static FormatLog flog;

        flog.ParseFormat(str);
    }
}

现在你可以简单地写:

Format = (FORMAT) GetProcAddress(hModule, "doParseFormat");

我个人觉得它更干净,您可以轻松使用它。

关于c++ - 在 C++ 中的不同项目文件中将参数)传递给函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32157390/

相关文章:

c++ - 你能在第 3 方 dll 中使用 std::string 吗?

c++ - 在 C++ 中实例化对象的不同方法

c++ - 在 C++/WRL 中使用静态方法创建 WinRT 组件

C++从模板参数类型生成包含开关/映射的函数体

c++ - 如何让 Sublime Text 自动选择自定义构建系统?

C++ 正则表达式和占位符

c++ - 为什么在键检查 map::emplace 之前调用对象的构造函数

c++ - 像 C# 中的 MFC 通用控件插件?

C语法错误: missing ';' before 'type'

c++ - 使用 Visual C++ 2010 编译器在 code::block 中使用 widgets 库时,发生错误