是否可以从XML文件动态构建函数声明?

时间:2012-01-12 11:35:50

标签: c++ windows

这是我正在探索插件框架的场景:

第三方插件开发人员使用已知的入口点和任意参数设计DLL。它们还提供XML文件中入口点和参数的详细信息,并提供在调用插件时我们的程序将回调它们的数据。他们将能够在XML中使用一组可扩展的变量,我的程序将扩展它们并通过它们指定的参数传回给它们。

我知道在win32中我可以使用LoadLibrary / GetProcAddress来获取他们定义的函数。我不太清楚的是,我是否可以从他们定义的参数动态生成函数规范,我可以使用它来回调它们。有人知道这是否可行?

3 个答案:

答案 0 :(得分:1)

c ++不支持反射。

但是,使用pococapsule库可以(在某种程度上)。


This article详细介绍了如何构建插件框架。

答案 1 :(得分:1)

我决定做的只是让插件接受一个简单的界面:

DWORD func ( LPARAM pBuf, DWORD size );

这将允许用户在XML中指定他们的参数,然后定义他们希望我传递的结构,例如

typedef struct
{
    int a;
    float b;
    double c;
    wchar_t * d;
} test1;

当他们收到我的消息时,他们可以在使用缓冲区之前检查大小,以确保XML和结构匹配。

在解析XML时,我使用此类和模板方法来动态构造对象:

class DynamicStructure
{
public:

    template <typename T>
    void addField(const T & field)
    {
        m_mapPtrSize.push_back(std::make_pair(reinterpret_cast<const LPARAM>(&field), sizeof(T)));
    }

    DWORD getSize()
    {
        //
        // Work out the combined size of all the fields
        DWORD sSize = 0;
        for ( auto it = m_mapPtrSize.cbegin(); it != m_mapPtrSize.cend(); it++ )
        {
            sSize += it->second;
        }

        return sSize;
    }

    LPARAM getBuffer()
    {
        // Create a buffer big enough for all the fields
        //
        LPARAM pBuf = reinterpret_cast<LPARAM> (new (std::nothrow) BYTE[getSize()]);

        if (pBuf == NULL)
            return NULL;

        DWORD offset = 0;
        for ( auto it = m_mapPtrSize.cbegin(); it != m_mapPtrSize.cend(); it++ )
        {
            // Copy the fields one at a time, offsetting into the buffer
            //
            memcpy( (void*) (pBuf + offset), (const void*) it->first, it->second);
            offset += it->second;
        }

        return pBuf;
    }

protected:
private:
    std::vector<std::pair<const LPARAM, DWORD>> m_mapPtrSize;
};

这允许我在解析XML时执行以下操作:

DynamicStructure dynStruct;
int a = 1;
float b = 2.3f;
double c = 3.5;
wchar_t * d = L"bob";

dynStruct.addField(a);
dynStruct.addField(b);
dynStruct.addField(c);
dynStruct.addField(d);

// Test - does the dymanic structure match the user's structure?
LPARAM pBuf = dynStruct.getBuffer();
test1 * pTest1 = (test1 *) pBuf;

std::wcout << pTest1->a << " " << pTest1->b << " " << pTest1->c << " " << pTest1->d << std::endl;

它并不完美,它有点老派,但至少它很简单并且提供了合理的安全水平。

答案 2 :(得分:0)

你不能在运行时构建函数,所以你留下了编译时选项,比如模板元编程。