Using libuv inside classes - c++

I am trying to write a nodejs bindings for a C++ library and I seem to have hit a roadblock.
I am working on trying to make all the calls to the C++ library asynchronous and thats why I am using libuv. I am basically following this tutorial.
I want to be able to call class member functions from libuv's uv_queue_work. Have a look at this code --
class test {
private:
int data;
void Work(uv_work_t *req);
void After(uv_work_t *req);
public:
Handle<Value> Async(const Arguments& args) {
HandleScope scope;
Local<Function> callback = Local<Function>::Cast(args[0]);
int status = uv_queue_work(uv_default_loop(), **something**, Work, After);
assert(status == 0);
return Undefined();
}
};
Basically I expect the Work and After functions to work on the data element of the class. However this doesnt seem to work. I have tried typecasting the pointers to Work and After after from type void test::(*)(uv_work_t*) to void (*)(uv_work_t*). But that also doesnt seem to work.
Could you guys give me some tips on how to work around this??

So as you've realized, you cannot call the member functions directly.
The second argument "something" is of type uv_work_t, which has a member "void* data".
What you will need to do is create static methods inside your class for "Work" and "After", create a uv_work_t structure, and assign data to "this".
Once that is done inside your static "Work" and "After" methods you do a static cast on "req->data" (To your class type) and then call your member functions.
For example:
uv_work_t* baton = new uv_work_t();
baton->data = this;
int status = uv_queue_work(uv_default_loop(), baton, StaticWork, StaticAfter);
And then in the static methods
test* myobj = static_cast<test>(req->data);
myobj->Work();
And similar code for the StaticAfter function

Related

Pointer to function from another pointer

I'm new to c++ and I'm trying to make a generic switch (i.e. the device, not the C++ statement) that could be used to blink lights, turn beeps on and off, etc, in my Arduino project.
I could create a switchable interface and implement that in the classes that I want to "switch". But since I'm doing it as study purposes and I saw the pointer-to-functions ability in C++ (that is new to me since I come from C# and Java), I tough it would be a good opportunity to give it a try...
The problem is that I can pass the function in my code only if it's a local function but it won't work if I try to pass a function from another object like a led for example.
Some code to illustrate the problem. This is the switch.cpp, it recieves the On and Off functions in it's constructor and it has a update method that is called inside the loop method in the Arduino ino main class:
auto_switch.cpp
using switch_function = void(*)();
auto_switch::auto_switch(const switch_function on_function, const switch_function off_function, const int max_speed_count)
{
//sets all variables...
}
void auto_switch::update(const unsigned long millis)
{
//turn switch on and off...
}
And this is my ino file
ino file
#include <Arduino.h>
#include "led.h"
#include "auto_switch.h"
led* main_led;
auto_switch* led_switch;
int slow_speed;
//ugly code
void turn_led_on()
{
main_led->turn_on();
}
//ugly code
void turn_led_off()
{
main_led->turn_off();
}
void setup() {
main_led = new led(2, 3, 4, true, color::white);
//ugly code
led_switch = new auto_switch(turn_led_on, turn_led_off, 3);
slow_speed = led_switch->add_speed(100, 100, 3, 1000);
led_switch->set_active_speed(slow_speed);
led_switch->turn_on();
}
void loop() {
led_switch->update(millis());
}
It works but I had to make a local function (turn_led_on and turn_led_off) to be able to assign the inner functions as a parameter to the auto_switch constructor, the parts that I've wrote //ugly code
I wanted to do something like this, without the glue code in between:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
Is it possible? I've read something about static pointer to function and some std functions that help with that, if I get it right the glue code is necessary in this case so that the compiler can know where the functions are coming from I guess (from which object), but since the functions I need to call cannot be static I've discarded this option, and the std functions I believe it can't be used with the Arduino or could but shouldn't for performance limitations...
Anyway, does it make sense, can it be done using pointer to functions or should I create a interface or something different?
Before deciding how to do it, the qquestion is what do you want to do and why. Because, maybe there are better alternatives using simple C++ idioms.
Option 1: specialization with polymorphism
Do you want to specialize some functions of your switch, so instead of calling the function of the auto_switch you'd call dome more specialized ones ?
In this case you wouldn't do:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
but instead you would rely on polymorphism with virtual functions in the base class:
class auto_switch {
...
virtual void turn_on();
virtual void turn_off();
...
};
and write a specialized class for the leds:
class led_witch : public auto_switch {
...
void turn_on() override;
void turn_off() override;
...
};
In fact, the compiler will generate some function pointers behind the scene, but you don't have to care:
auto_switch s1=new auto_switch(...);
auto_switch s2=new led_switch(...); // no problem !!
s1->turn_on(); // calls auto_switch::turn_on()
s2->turn_on(); // calls led_switch::turn_on() since the real type of s2 is led_switch
But event if each object's behavior is dynamic on the the base of the real class of the object, the objects of the same class share a behavior that was predefined at compile time. If this is not ok, go to the next option.
Option 2: the member function pointer
The functions of another objects can only be invoked with that object at hand. So having a function pointer to a led function is not sufficient: you also need to know on which led it shall be applied.
This is why member function pointers are different and somewhat constraint: you can only invoke functions of class of your member function pointer. If polymorphism is sufficient (i.e. if derived class has a different implementation of a function already foreseen in the base classe) then you are lucky. If you want to use a function that only exists in the derived class and not in the base class, it won't compile.
Here a simplified version of auto_swith: I provide a function, but allso a pointer to the object on which the function has to be invoked:
class auto_switch{
void (led::*action)();
led *ld;
public:
auto_switch(void(led::*a)(), led*l) : action(a), ld(l) {}
void go () { (ld->*action)(); }
};
// usage:
auto_switch s(&led::turn_off, &l1);
s.go();
Online demo
Option 3 : the functional way (may that's what you're looking for ?)
Another variant would be to use the standard functional library to bind a member function and the object on which it shall be executed (as well as any need parameters):
class auto_switch{
std::function<void()> action;
public:
auto_switch(function<void()>a) : action(a) {}
void go () { action(); }
};
Here you can bind anything: any function of any class:
auto_switch s(bind(&led::turn_off, l1));
s.go();
auto_switch s2(bind(&blinking_led::blink, l2));
s2.go();
Online demo
Option 4 : command pattern
Now if you want to perform something on an object when you turn on and off the switch, but you need total flexibility, you can just implement the command pattern : this lets you execute anything on any object. And you don't even need a function pointer.

Passing an instance method to an API that expects a C function pointer

I have a C API to a data source. To be notified that new data is available you give the API a callback in the form of a function pointer; your callback will be called when data comes in. The API’s header contains lines like this:
struct DataRecord { ... };
typedef void (*DataCallback)(DataRecord *data);
void set_data_callback(DataCallback processor);
My C++ class has an instance method with the signature
void MyClass::process_data(DataRecord *data);
and in the constructor of MyClass I’d like to set the new instance’s process_data method as the data callback for the C API. Following this answer I tried to write this code in the constructor:
typedef void (MyClass::data_callback_t)(DataRecord*);
data_callback_t callback = &MyClass::process_data;
set_data_callback(callback);
When I do this I get the error
error C2664: 'set_data_callback' : cannot convert parameter 2 from 'data_callback_t' to 'DataCallback'
There is no context in which this conversion is possible
(I am using Visual C++ 2010 Express, although I hope that doesn’t make a difference.)
How can I extract a C function pointer from an instance and a method?
You can't. MyClass::process_data can be thought of as a void(MyClass*, DataRecord*), which is the wrong type. You'd have to wrap your class pointer into the call somehow.
One approach might be to introduce a type with a static pointer:
struct MyClassCallbackHelper
{
static MyClass* myClass;
static void callback(DataRecord* record) {
myClass->process_data(record);
}
};
So that you can do:
MyClassCallbackHelper::myClass = this;
set_data_callback(&MyClassCallbackHelper::callback);

Binding C++ functions & calling Lua functions with class as parameter

I've been reading about Lua/C++ and I had a question about design I was hoping I could get some help on.
What I want:
I want so my class in C++ (Created and Destroyed by C++) to be able to call
a Lua function using itself as a parameter.
Eg.
object.h
class Object
{
public:
Object(const std::string & onLoad, const std::string & onEvent);
~Object();
void OnLoad();
void RegisterEvent(const std::string & eventID);
void OnEvent(const std::string & eventID);
void SetValue(int value);
private:
int m_value;
std::string m_onLoad;
std::string m_onEvent;
};
object.cpp
Object::Object(const std::string & onLoad, const std::string & onEvent)
: m_value(0)
, m_onLoad(onLoad)
, m_onEvent(onEvent)
{
}
Object::~Object()
{
GAME->GetEventManager()->UnregisterListener(this);
}
void Object::OnLoad()
{
//
// call lua function [name store in: m_onLoad]
// eg. m_onLoad = Object_OnLoad
// in lua ->
// function Object_OnLoad(object)
//
}
void Object::RegisterEvent(const std::string & eventID)
{
GAME->GetEventManager()->RegisterEvent(this, eventID);
}
void Object::OnEvent()
{
//
// call lua function [name store in: m_onEvent]
// eg. m_onEvent = Object_OnEvent
// in lua ->
// function Object_OnEvent(object, eventID)
//
}
void Object::SetValue(int value)
{
m_value = value;
}
script.lua
function Object_OnLoad(object)
object:RegisterEvent("EVENT_CURRENT_HEALTH_CHANGED")
end
function Object_OnEvent(object, eventID)
if (eventID == "EVENT_CURRENT_HEALTH_CHANGED")
object:SetValue(GetCurrentHealth());
end
test.cpp
Object *pTest = new Object("Object_OnLoad", "Object_OnEvent");
pTest->OnLoad();
GAME->GetEventManager()->TriggerEvent(CEvent("EVENT_CURRENT_HEALTH_CHANGED"));
delete pTest;
After Some reading:
From what I've read this is no direct way to assign C++ class instance functions.
Non-member functions are needed. Tables are used to track functions.
My Questions:
What do I push as an argument when calling the Lua functions (Object_OnEvent(object, eventID) etc...) Is it a pointer to the object
How does Lua know the object design
Do I need a table per object or instance
Do I need to duplicate all the functions I intend to use in Lua again as normal functions grabbing a the ptr to call it from
As a final and possible single question:
Is there any place I could get more information on what I'm trying to achieve described above.
I'm probably just going to go back to step one and try and absorb this information again.
I still wan't to make my post tho. I'll post back myself if I set it up.
There are many questions, but in principle, if I understand you correctly, you want to bind your C++ classes to Lua, have a shared object lifetime and automatic garbage collection, and be able to call Lua functions on objects created on the C++ side.
This is all possible with either low-level glue code, or dedicated binding libraries, such as LuaBridge and LuaState. LuaState is used in my answer for convenience and fast prototyping.
What's not yet clear is why you want to define a trivial function in Lua, such as Object_OnLoad to call it from C++, which would call a method of an object that you have created in the same scope on the C++ side. I'd guess, you have a more complicated picture in your code, so that such Lua usage pattern would be justified. In that case, one by one:
The ingredients
Binding a class to Lua
Here's a declarative binding that you can call once before calling any other Lua functions
void luabridge_bind(lua_State *L) {
luabridge::getGlobalNamespace(L)
.beginClass<MyObject>("MyObject")
.addConstructor<void(*)(), RefCountedPtr<MyObject> /* creation policy */ >()
.addFunction("RegisterEvent", &MyObject::RegisterEvent)
.endClass()
;
}
To perform the binding:
lua::State state;
luabridge_bind(state.getState());
Calling a lua function on a C++ side object
LuaState unfortunately cannot use objects in call parameters at the moment, while primitives work, i.e. from the readme:
state.doString("function add(x, y) return x + y end");
int result = state["add"](1,2);
But what one could do is to temporary create a global variable instance (watch out for name collisions) and call the function on it.
Preparing the script:
static const char *script =
"function Object_OnLoad(object)\n"
" object:RegisterEvent('EVENT_CURRENT_HEALTH_CHANGED')\n"
"end"
;
state.doString(script);
Creating an automatically lifetime-managed object:
auto my_obj = RefCountedPtr<MyObject>(new MyObject);
Calling the lua function on the object:
SetGlobal(state.getState(), "my_obj", my_obj);
state.doString("Object_OnLoad(my_obj); my_obj = nil");
Where SetGlobal can look like that:
template <typename T>
void SetGlobal(lua_State* L, const char *name, T value) {
luabridge::push(L, value);
lua_setglobal(L, name);
}
A complete example and comments
You can find the whole example code at Github: try_luabridge.cpp
which has been compiled and run at Travis CI.
The possibilities are limitless. It's up to you how you structure your code, so, naturally, this answer won't provide code that would immediately fit your needs. However, I'd encourage you to read Programming in Lua, and LuaBridge and LuaState manuals to get a better overview of the possiblities that are at your hand.

Using SQLite in C++: object function as a callback

So, I am working on a side-project to keep my c++ skills fresh (it has been many years since I have done work in c++). I am working on something where I will be using SQLite. I have a wrapper around the SQLite code. One of the things I am noticing is that SQLite uses c-style callback functions in its sqlite3_exec(...) function.
I would like to have the callback function be an object method, as I would like it to be able to modify object variables but am unsure of how to do this exactly. I have checked other similar questions on stackoverflow but came away with nothing helpful.
Here is how I am declaring my wrapper class:
class DBAdapter
{
private:
sqlite3* db;
int getUserRecords(std::string);
std::vector<USER_RECORD> records;
int callbackSel(void*, int , char**, char**);
public:
DBAdapter();
~DBAdapter();
int open(std::string);
void close();
int insertRecord();
int deleteRecord();
int getNumUserRecords();
};
Here is how I am trying to use the callback (callbackSel), from within getNumUserRecords:
int DBAdapter::getUserRecords(std::string name)
{
std::string sql = "SELECT" + name + " from USERS";
char* ErrMsg;
char* data;
int retval = sqlite3_exec(db,sql.c_str(),this->callbackSel,data,&ErrMsg);
return retval;
}
The error message I am getting is:
error: ‘int (* DBAdapter::callbackSel)(void*, int, char**, char**)’ is not a static member of ‘class DBAdapter’
My problem is, if I make this a static function, I won't be able to have access to my vector, records, right? Is there any way around this?
Is there any way around this?
I don't know for sqlite API specifically, but usually c-style callbacks support to have user data passed from a void* pointer (I'd guess the 1st parameter of that signature you mention). What one typically does is:
Declare a static class function to specify as callback function pointer
Implement that function to cast the passed user data pointer to a pointer to your class instance and call a member function
Have a member function defined in the class that provides the implementation you want
Pass a pointer to your handling class instance, when you're going to register the static member function pointer with the C API
I hope this points out the right direction.

Function pointer to class member function problems

First of all I have to admit that my programming skills are pretty limited and I took over a (really small) existing C++ OOP project where I try to push my own stuff in. Unfortunately I'm experiencing a problem which goes beyond my knowledge and I hope to find some help here. I'm working with a third party library (which cannot be changed) for grabbing images from a camera and will use some placeholder names here.
The third party library has a function "ThirdPartyGrab" to start a continuous live grab and takes a pointer to a function which will be called every time a new frame arrives. So in a normal C application it goes like this:
ThirdPartyGrab (HookFunction);
"HookFunction" needs to be declared as:
long _stdcall HookFunction (long, long, void*);
or "BUF_HOOK_FUNCTION_PTR" which is declared as
typedef long (_stdcall *HOOK_FUNCTION_PTR) (long, long, void*);
Now I have a C++ application and a class "MyFrameGrabber" which should encapsulate everything I do. So I put in the hook function as a private member like this:
long _stdcall HookFunction (long, long, void*);
Also there is a public void function "StartGrab" in my class which should start the Grab. Inside I try to call:
ThirdPartyGrab (..., HookFunction, ...);
which (not surprisingly) fails. It says that the function call to MyFrameGrabber::HookFunction misses the argument list and I should try to use &MyFrameGrabber::HookFunction to create a pointer instead. However passing "&MyFrameGrabber::HookFunction" instead results in another error that this cannot be converted to BUF_HOOK_FUNCTION_PTR.
After reading through the C++ FAQ function pointers I think I understand the problem but can't make up a solution. I tried to make the hook function static but this also results in a conversion error. I also thought of putting the hook function outside of the class but I need to use class functions inside the hook function. Is there another way or do I need to change my whole concept?
EDIT 14.01.08:
I tested the singleton workaround since I cannot change the third party library and the void pointer is only for data that is used inside the hook function. Unfortunately it didn't worked out of the box like I hoped.... I don't know if the static function needs to be in a separate class so I put it in my "MyFrameGrabber" class:
static MyFrameGrabber& instance()
{
static MyFrameGrabber _instance;
return _instance;
}
long Hook(long, long, void*); // Implementation is in a separate cpp file
In my cpp file I have the call_hook function:
long MFTYPE call_hook(long x, MIL_ID y, void MPTYPE *z)
{
return MyFrameGrabber::instance().Hook(x,y,z);
}
void
MyFrameGrabber::grab ()
{
ThirdPartyGrab(..., call_hook, ...);
}
But this gives me an error in static MatroxFrameGrabber _instance; that no matching standard constructor is found. That's correct because my MyFrameGrabber constructor looks like this:
MyFrameGrabber (void* x,
const std::string &y, int z,
std::string &zz);
I tried to put in an empty constructor MyFrameGrabber(); but this results in a linker error. Should I pass empty parameters to the MyFrameGrabber constructor in the singleton? Or do I need to have a separate Hook Class and if yes how could I access MyFrameGrabber functions? Thanks in advance.
SECOND EDIT 15.01.08:
I applied the changes and it compiles and links now. Unfortunately I cannot test this at runtime yet because it's a DLL and I have no Debug Caller Exe yet and there are other problems during initialization etc. I will mark the post as answer because I'm sure this is the right way to do this.
Your private member method has an implicit this pointer as first argument. If you write that out, it's obvious that the function signatures do not match.
You need to write a static member function, which can be passed as the callback-function to the library. The last argument to the HookFunction, a void*, looks to me very much like a cookie, where one can pass ones own pointer in.
So, all in all, it should be something like this:
class MyClass {
long MyCallback(long, long) {
// implement your callback code here
}
static long __stdcall ThirdPartyGrabCallback(long a, long b, void* self) {
return reinterpret_cast<MyClass*>(self)->MyCallback(a, b);
}
public:
void StartGrab() {
ThirdPartyGrab(..., &MyClass::ThirdPartyGrabCallback, ..., this, ...);
}
};
This of course only works if the void* argument is doing what I said. The position of the this in the ThirdPartyGrab() call should be easy to find when having the complete function signature including the parameter names available.
The reason "&MyFrameGrabber::HookFunction" cannot be converted to a BUF_HOOK_FUNCTION_PTR is that, being a member of the class, it has implicitly as first parameter the "this" pointer, thus you cannot convert a member function to a non-member function: the two signatures look the same but are actually different.
I would declare an interface, defining the function to call, have your class implement it and pass the object itself instead of the callback (you can think of an interface as the object-oriented replacement of a function pointer):
class IHookInterface{
public:
virtual long HookFunction(long, long, void*) = 0;
};
class HookClass : public IHookInterface{
public:
virtual long Hook(long, long, void*) {
// your code here...
}
};
// new definition:
ThirdPartyGrab (..., IHookInterface, ...);
EDIT - other possible solution in case you cannot modify the library: use a singleton rather than a static function.
class HookClass{
public:
static HookClass& instance(){
static HookClass _instance;
return _instance;
}
long Hook(long, long, void*) {
// your code here...
}
};
long call_hook(long x,long y,void * z){
return HookClass::instance().Hook(x,y,z);
}
SECOND EDIT: you might slightly modify the singleton class with an initialization method to call the constructor with the proper parameters, but maybe it is not more elegant than the following solution, which is simpler:
class HookClass{
public:
HookClass(string x,string y...){
}
long Hook(long, long, void*) {
// your code here...
}
};
static HookClass * hook_instance = 0;
long call_hook(long x,long y,void * z){
if (0 != hook_instance){
return hook_instance->Hook(x,y,z);
}
}
int main(){
hook_instance = new HookClass("x","y");
ThirdPartyGrab(..., call_hook, ...);
}