使用C ++中的不同项目文件将参数传递给函数

时间:2015-08-22 14:44:49

标签: 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);
        }
    }
};

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

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

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

我的问题是,如果我使用GetProcAddressLoadLibrary来调用调用任何方法的.dll文件,那么我不应该合法地传递除int,double,long之外的任何参数。那么请求方法?

1 个答案:

答案 0 :(得分:1)

您的代码中存在一个主要问题:.main-navigation ul .current-menu-item ul { display: block; } 一个函数接受LPWSTR并返回void但是类ParseFormat的实例方法。不同之处在于,对于实例方法,您有一个隐藏的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; } 手动导入它们,我只会从DLL中导出extern "C"个函数。

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

GetProcAddress

现在你可以简单地写一下:

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

        flog.ParseFormat(str);
    }
}

我个人发现它更干净,你可以轻松使用它。