Domanda

I have header (fingisdk.h) file like this:

#ifndef FINGISDK_H_
#define FINGISDK_H_

#include "fingienum.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef void (*fingi_event)(FINGI_EVENT_ID eventId, char* msg);

FINGI_EVENT_ID start_fingi_sdk(char* ini_file_location);
FINGI_EVENT_ID download_room_info(char** roominfo);

void register_fingi_sdk_status_event_listener(fingi_event pointer_to_listener_fnc);


#ifdef __cplusplus
}
#endif
#endif

And then i have written a python Wrapper for this one:

#include <fingisdk.h>
#include <fingienum.h>
#include <boost/python.hpp>


BOOST_PYTHON_MODULE(libpythonWrapper)
{
    using namespace boost::python;
    def("start_fingi_sdk", start_fingi_sdk);


}

And python file for calling it is like this:

import libpythonWrapper

print libpythonWrapper.start_fingi_sdk('file_location.ini')

So far this works fine. However, i can not find out how to expose double the double pointer function :

FINGI_EVENT_ID download_room_info(char** roominfo);

And callback function :

void register_fingi_sdk_status_event_listener(fingi_event pointer_to_listener_fnc);

Can anyone point me to some documentation or help me solve it

Thankyou


EDIT 1:

After messing around a bit, i figured out how to do the pointer to pointer function . Python does not support pointer , so have to wrap the download_room_info(char** roominfo) to return simple string:

std::string download_room_info_python_wrapper() {
    char * value;
    FINGI_EVENT_ID result = download_room_info(&value);
    return std::string(value);
}

And then:

def("download_room_info", download_room_info_python_wrapper);

Still looking for solution for callback function

È stato utile?

Soluzione

So you want to bind this API to Python:

typedef void (*fingi_event)(FINGI_EVENT_ID eventId, char* msg);
void register_fingi_sdk_status_event_listener(fingi_event);

That's a register function which takes a function which takes an eventId and a string. OK, let's define one of our own (in extern "C" of course, as the API is):

void my_callback(FINGI_EVENT_ID eventId, char* msg)
{
  // do something
}

Now we can write a wrapper for the register function:

void my_register()
{
  register_fingi_sdk_status_event_listener(my_callback);
}

And bind it:

def("my_register", my_register);

That should all work. But it's useless, because we didn't actually do anything in the callback. So this leads to a sub-question, which is how can you possibly do anything in the callback? One idea I have is that you should make your own function registration mechanism which lets you register a Python callback function into something like a global PyObject which will be set to a Python function and invoked using Boost Python:

boost::python::object g_callback;
void my_callback(FINGI_EVENT_ID eventId, char* msg)
{
  if (g_callback)
    g_callback(eventId, msg);
}

Now it's just a matter of letting the user assign the global callback:

void set_callback(boost::python::object func)
{
  g_callback = func;
  register_fingi_sdk_status_event_listener(my_callback);
}

def("set_callback", set_callback);

Then in Python:

def callback(eventId, msg):
  print eventId, msg

set_callback(callback)

That should be about it, I think. This whole thing would be a ton easier if your callback API supported a "void* userData" argument like many callback APIs do. We'd then use that to store a PyObject or something useful. But the API lacks that, so we're stuck with a global somewhere to remember which function to call.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top