Как правильно запускать события браузера из Python, используя boost и Firebreath - PullRequest
3 голосов
/ 16 февраля 2012

Сначала я должен сказать, что, как программист на Python, я мог видеть эту проблему с неправильной точки зрения, прошло много лет с тех пор, как я написал свой последний код на C ++ в колледже.

У меняНемного проблем, пытаясь создать гибридный плагин Python / C ++, используя Firebreath.До сих пор я успешно интегрировал все части, используя boost / python.h, но проблема возникла, когда я попытался запустить событие из Python.Я столкнулся с проблемой необходимости связывать воедино функцию python с функцией c ++ (используя BOOST_PYTHON_MODULE).Сначала я попытался напрямую связать python с моим производным JSAPI-классом fbtestconpythonAPI. Проблема этого подхода, по-видимому, заключается в отсутствии ссылки на объект JSAPI, созданный браузером, что дает мне все виды проблем несоответствия сигнатур между функцией python и эквивалентом c ++ ввремя исполнения.

Единственное, что мне пришло в голову, чтобы это исправить (я согласен, это уродливое грязное решение), это использовать глобальный указатель, который я инициализирую вручную с помощью set_pluginPointer.Это на самом деле работает довольно хорошо, но я знаю, что это не правильный способ сделать это.Я прочитал, что не должен использовать «необработанный» указатель с объектом JSAPI, но я не уверен, как заменить его на shared_ptr для этой конкретной реализации.Другая проблема - это глобальная переменная, которая распределяется между всеми экземплярами, что приводит, например, к тому, что все события запускаются на последней открытой вкладке / окне.Одним из способов решения этой проблемы было бы создание какого-либо массива с индексом, являющимся текущим идентификатором окна / потока, к которому я должен иметь доступ как из моего объекта JSAPI, так и из функции python / c ++.

Конечно, я открыт и буду очень признателен за любые предложения о том, как улучшить / исправить этот конкретный обходной путь или, что лучше, правильный способ взаимодействия boost :: python и firebreath без взлома.

Ниже приведена соответствующая часть кода плагина

// Global pointer to plugin instance
fbtestconpythonAPI *fbtestPtr;
void fbtestconpythonAPI::set_pluginPointer(const std::string& val){
    m_testString = val;
    fbtestPtr = this; //Global pointer initialization
}

void echo(std::string x){
    // Firing the echo event on the plugin instance using the global raw pointer
    fbtestPtr->fire_echo(x, 1);
}

BOOST_PYTHON_MODULE(Pointless) {
    def("echo", echo);
}

FB::variant fbtestconpythonAPI::echo(const FB::variant& msg){
    int result_value;
    Py_Initialize(); 

    try {
        initPointless(); // initialize Pointless

        PyRun_SimpleString("import Pointless");
        PyRun_SimpleString("Pointless.echo('hello world')");

        object module(handle<>(borrowed(PyImport_AddModule("__main__"))));
        object dictionary = module.attr("__dict__");
    } catch (error_already_set) {
        PyErr_Print();
    }

    Py_Finalize();
    return 0;
}

1 Ответ

1 голос
/ 17 февраля 2012

При быстром просмотре вы настроите свой класс для экспорта следующим образом:

class_<YourAPI, boost::noncopyable>("YourAPI", no_init)
    .def("function", &YourAPI::function);

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

...