2012-02-16 1 views
3

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

У меня возникла небольшая проблема, пытаясь создать гибридный плагин 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; 
} 
+0

Я еще не работал с Boost.Python, но, похоже, вам следует изучить, как получить объекты Python, связанные с экземплярами плагина FireBreath, вместо того, чтобы пытаться использовать обходной путь (свободные функции + глобальные). Я рекомендую задать вопрос об этой первоначальной проблеме. –

+0

Спасибо за комментарий. Возможно, я был не очень ясен, пожалуйста, простите меня, потому что английский не мой первый язык, я имел в виду, что любое предложение о том, как это сделать (connect boost: python with firebreath), будет высоко оценено. Я просто хотел поделиться решением, которое я придумал, чтобы это исходило из ответов – skalanux

+0

Я вижу, тогда я просто неправильно вас понял. –

ответ

1

С быстрым взглядом вы хотите настроить ваш класс для экспорта, как это:

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

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

+0

Большое спасибо Георг. Я сразу начну рассматривать это – skalanux