Можно ли динамически создавать объявления функций из файла XML? - PullRequest
1 голос
/ 12 января 2012

Вот сценарий, который я изучаю для платформы плагинов:

Сторонний разработчик плагинов разрабатывает DLL с известной точкой входа и произвольными параметрами. Они также предоставляют подробную информацию о точке входа и параметрах в XML-файле и предоставляют данные, с которыми они будут вызываться моей программой при вызове плагина. Они смогут использовать в XML набор расширяемых переменных, которые моя программа расширит и передаст им через заданные параметры.

Я знаю, что в win32 я могу использовать LoadLibrary / GetProcAddress, чтобы получить функцию, которую они определяют. Что мне менее понятно, так это то, могу ли я динамически генерировать спецификацию функции из их определенных параметров, которые я могу использовать для их обратного вызова. Кто-нибудь знает, возможно ли это?

Ответы [ 3 ]

1 голос
/ 12 января 2012

C ++ не поддерживает отражение.

Однако это возможно (до некоторой степени) при использовании библиотеки pococapsule .


В этой статье подробно рассказывается, как создать фреймворк для плагина.

1 голос
/ 12 января 2012

Я решил просто заставить плагины принимать простой интерфейс:

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;

Это не идеально, и это немного старая школа, но, по крайней мере, это просто и обеспечивает разумный уровень безопасности.

0 голосов
/ 12 января 2012

вы не можете создавать функции во время выполнения, поэтому у вас остались опции времени компиляции, такие как метапрограммирование шаблонов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...