这是我正在探索插件框架的场景:
第三方插件开发人员使用已知的入口点和任意参数设计DLL。它们还提供XML文件中入口点和参数的详细信息,并提供在调用插件时我们的程序将回调它们的数据。他们将能够在XML中使用一组可扩展的变量,我的程序将扩展它们并通过它们指定的参数传回给它们。
我知道在win32中我可以使用LoadLibrary / GetProcAddress来获取他们定义的函数。我不太清楚的是,我是否可以从他们定义的参数动态生成函数规范,我可以使用它来回调它们。有人知道这是否可行?
答案 0 :(得分:1)
答案 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)
你不能在运行时构建函数,所以你留下了编译时选项,比如模板元编程。