3

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

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.