How to give a instance a function from a library in C? - c++

I wanted to give the aRest library
a function to expose to the api.
But I am importing a customlibrary,
I wanted to give the aRest instance a function in that library.
This is my code
#include <ESP8266mDNS.h>
#include <ESP8266WiFi.h>
#include <aREST.h>
#include <EEPROM.h>
#include <WiFiClient.h>
//My Custom Made C/C++ Libraries
#include <DeviceEeprom.h>
#include <DeviceRoute.h>
//Creating my customLib instances
DeviceEeprom deviceEeprom = DeviceEeprom();
DeviceRoute deviceRoute = DeviceRoute();
// Create aREST instance
aREST rest = aREST();
int myFunction();
void setup()
{
Serial.begin(115200);
rest.set_id("1");
rest.set_name("esp8266");
rest.function("myFunction" &myFunction);
}
void loop()
{
}
int myFunction()
{
return 1;
}
I wanted to go from this.
rest.set_function("myFunction" &myFunction);
To this.
rest.set_function("myFunction" deviceRoute.myFunction());
UPDATE
I found the rest.function() code
This is the code
void function(char * function_name, int (*f)(String)){
functions_names[functions_index] = function_name;
functions[functions_index] = f;
functions_index++;
}
Mayby this helps out?

There's no way to pass a pointer to a non-static member function directly to aREST::function.
Non-static member functions are different than static member functions and freestanding functions. They require an object to work on. That means that &DeviceRoute::myFunction is not compatible with the type int(*)(String). Instead it's a int (DeviceRoute::*)(String).
To make this work, you need a static or freestanding wrapper function that calls the member function you want. Since aREST::function doesn't accept any sort of context pointer, your only real option is to use a global variable:
//Creating my customLib instances
DeviceEeprom deviceEeprom;
DeviceRoute deviceRoute;
// Create aREST instance
aREST rest;
int myFunction(String s)
{
return deviceRoute.myFunction(s);
}
void setup()
{
Serial.begin(115200);
rest.set_id("1");
rest.set_name("esp8266");
rest.function("myFunction" &myFunction);
}
void loop()
{
}

Related

Pass an object to a class and call it in an static function in the same class

I am using gdal to do some raster works, well it has a GDALWarpAppOptionsSetProgress function which gets an static function to show its progcess. here you can find its link :Link
and this link
http://gdal.sourcearchive.com/documentation/1.6.0/gdal_8h_5703b651695c0cbe6f3644a0a18dda8b.html
well I know I must write an static function to use it, here is my function
static int My_FN_GDALTermProgress( double dfComplete, const char *pszMessage, void *pData)
{
if(progressBar){
progressBar->setValue(FN_GDAL_PROGRESS_VALUE);
}
double FN_GDAL_PROGRESS_VALUE = dfComplete * 100;
return TRUE;
}
well i have a class named gdal_dem which is like this
#include "gdal_dem.h"
#include "gdal_wrap.h"
#include <qdebug.h>
#include <iostream>
#include "cpl_string.h"
#include "gdal_priv.h"
#include "ogr_spatialref.h"
#include "gdal_utils_priv.h"
#include "cpl_error.h"
#include <QString>
#include "commonutils.h"
#include <QFile>
gdal_dem::gdal_dem(QString SrcFilename):
SrcFile(SrcFilename)
{
}
float FN_GDAL_PROGRESS_VALUE = 0.0f;
static int My_FN_GDALTermProgress(double dfComplete,
CPL_UNUSED const char * pszMessage,
CPL_UNUSED void * pProgressArg )
{
FN_GDAL_PROGRESS_VALUE = dfComplete * 100;
printf("Progress: %f\n",FN_GDAL_PROGRESS_VALUE);
return true;
}
////
int gdal_dem::colorrelief(QString Dstanationfile,QString colorfile){
.....
if(!(psOptionsForBinary->bQuiet))
{
prgFunc=My_FN_GDALTermProgress;
GDALDEMProcessingOptionsSetProgress(psOptions, prgFunc,NULL);
}
......
}
In above code I can set the above mentioned function in processing option and it works fine. but my problem is when I want to update a progress bar. I have a QProgressBar and it is in my main class. How can I pass it into the static function? I tried these ways:
1- I tried to get progressbar in my gdal_dem and also defined a static variable in gdal_dem and tried to set its value and update it in My_FN_GDALTermProgress, the problem is because progressbar is also static I can see it in wrap.cpp's contractor,
2-I tried to define a new My_FN_GDALTermProgress function in my main apps class but it must be static and I faced this error cannot declare member function to have static linkage
3- I also tried this method but it does not work
https://www.badprog.com/c-errors-warnings-cannot-declare-member-function-static-void-myclassmymethod-to-have-static-linkage
Well, How can I pass a parameter to my gdal_dem class and update its value in an static class in it?
Use the pData argument. You can pass anything you want to it when registering the static function. In this case, you can pass a pointer to your QProgressBar object:
QProgressBar* qProgBarObj = // ...
GDALDEMProcessingOptionsSetProgress(psOptions, prgFunc, qProgBarObj);
The static function will then receive it as the third argument:
static int My_FN_GDALTermProgress(double dfComplete, const char *pszMessage, void *pData)
{
auto progBar = reinterpret_cast<QProgressBar*>(pData);
progBar->setValue(/* ... */);
// ...
}

Avoid exposing static variable for a default function argument

I have a function foo() that updates a global CAtlList. Now I want to reuse foo to update another list. Currently I achieve this using a default argument.
//header.h
extern CAtlList<data> globalList;
void foo(CAtlList<data> &somelist = globalList);
//file1.cpp
CAtlList<data> globalList;
void foo(CAtlList<data> &somelist)
{
//update somelist
}
//file2.cpp
#include "header.h"
foo();
and
CAtlList<data> anotherList;
foo(anotherList);
//use anotherList
But for the default scenario foo takes globalList by reference, which means globalList must be visible at the point of declaration. I had to expose and add an extern declaration of globalList for that to happen.
I'd rather not expose it, is it at all possible?
Use an overload, not a default parameter.
void foo();
void foo(CAtlList<data> &somelist);
It costs you 4 short lines of code in the .cpp: The body of the parameterless foo calling the 1-parameter foo with the correct argument. That's the total cost to get the expressiveness you desire. A default parameter is not the tool for your job.
I don't know you can avoid declaring a variable that's referenced as a default. However, you could simply overload the function:
//file1.h
void foo();
void foo(CAtlList<data> &somelist);
//file1.cpp
#include "file2.h"
CAtlList<data> globalList; // Local scope only
void foo(CAtlList<data> &somelist)
{
//update somelist
}
void foo()
{
foo(globalList);
}
A more modern way is to use the 'optional' class that's part of the C++ library:
http://en.cppreference.com/w/cpp/utility/optional
//file1.h
#include <optional>
void foo(optional<CAtlList<data>> &somelist);
//file1.cpp
#include "file1.h"
CAtlList<data> globalList; // Local scope only
void foo(optional<CAtlList<data>> &somelist){
if (somelist.has_value()) { /* update somelist */ }
else { /* update globalList */ }
}
However, I suspect that this will break the existing dependencies. If there are few and easy to fix, this is probably the way.
The other comments are also correct. You should try and avoid the use of global state wherever possible - its a symptom of poor design.

Invoking a member method pointer from another method

In class Foo I have two methods, assign_handler() and call_handler().
The actual handler code is in the main.cpp which is do_this(). do_this() uses the some global variables in main.cpp,
I think Foo has to have a function pointer as member which will be assigned in assign_handler() which is what I did. However I'm having trouble invoking assign_handler() i.e. calling do_this(), from call_handler().
Note: call_handler() itself is call by a sigaction in Foo.
EDIT: I tried producing a MCVE as suggested in the comments. I've used gedit to create the files and compile it using g++ in command line. The code works. However in my Eclipse project I get the errors shown in inline comments of the code.
MCVE:
//Foo.h
class Foo{
public:
void (*funptr)(void);
void call_handler();
void assign_handler (void(*func1)(void));
Foo(){};
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
funptr();//error: invalid use of member Foo::funptr in static member function; from this location
//or
//this->funptr();//error: 'this' is unavailable for static member functions
}
//main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
void do_this(void);
int main(void){
Foo foo;
foo.assign_handler(do_this);
foo.call_handler(); //this won't be called explicitly, it is assigned as a handler for a sigaction
int x;
cin>>x;
}
void do_this(void){
cout<<"done"<<endl;
}
I'll divide my answer in two parts. First I'll attempt to answer your question, then I'll attempt to tell you what you actually want to do.
Your question is how to assign a function pointer to a member variable and then call it from a static member function. Since the function pointer is a member of the class you will also require a pointer to the class in order to call the function pointer. A way of achieving this is to add a static member to your class that holds a pointer to the (single) instance of your class. Since you indicated that you will be using this as a signal handler, you won't want to use multiple handlers anyway.
So, something like this:
//Foo.h
class Foo{
public:
static void call_handler();
void assign_handler (void(*func1)(void));
Foo() {
ms_instance = this;
};
private:
void (*funptr)(void);
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
ms_instance->funptr();
}
A more general way would be to store a function object:
//Foo.h
#include <functional>
#include <utility>
class Foo{
public:
static void call_handler();
template<typename func>
void assign_handler (func&& handler)
{
m_handler = std::forward(handler);
}
Foo() {
ms_instance = this;
};
private:
std::function<void(void)> m_handler;
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::call_handler(){
ms_instance->m_handler();
}
This way you can assign lots of different stuff as the handler:
// Function pointers
foo.assign_handler(do_this);
// Lambdas
foo.assign_handler([]() { /* do something */ });
// Binds - you should probably prefer lambdas...
foo.assign_handler(std::bind(&MyClass::member_func, &myObj));
Now what you actually want to do when you are going to handle a signal is a bit more complicated. Remember that signal handlers can only call certain functions (async-signal-safe functions) - otherwise things may get ugly. Therefore there is a common trick that you should perform called the self pipe trick. Essentially you should have a signal handler that receives the signal, but only calls write on a pipe with the signal number as the data to send. Then you have another place in your code that calls select on the pipe and then read to read the signal number. You then call the appropriate handler function which is then allowed to do whatever you like.
An example of this is here: http://man7.org/tlpi/code/online/book/altio/self_pipe.c.html
Be aware that it can be slightly tricky to get this right in a cross-platform manner, especially if multithreaded.

Is there a way to declare a class then initialize it in a function in c++?

I would like to know if there was a way to declare a class before a function, and then initialize it inside of a function, something like this:
Application.h:
class Application
{
Application(HWND hwnd);
~Application() {}
};
Main.cpp:
#include "Application.h"
#include <Windows.h>
Application App;
int main()
{
App(hwnd);
return 0;
}
Application *pApp;
int main()
{
pApp = new Application(hwnd);
//use pApp
delete pApp;
return 0;
}
Using a pointer is pretty much the only way to do what you want to do.
You cannot initialize a global object inside a function, the constructor of the object will be called some time before the main function of the program is called. This is very bad, it involves the thing called static initialization fiasco and you want to avoid it. Try to search for singleton pattern implementation in C++, that's what you need probably.
In C++ the constructor for an object is called when the storage for it is allocated, you cannot call the constructor later like you tried to do.
You might consider not defining a constructor, and using a separate member function, for example init, to initialize your App object.
Application.h:
class Application
{
public:
void init(HWND hwnd);
};
Main.cpp:
#include "Application.h"
#include <Windows.h>
Application App;
int main()
{
App.init(hwnd);
return 0;
}

Use LuaBind to call Lua functions inside a class when Lua is bound inside THAT class

Basically, I just want to be able to have a clean Lua instance made inside of my Manager class, then export the functions in the class to Lua, so that I can call functions on the already created C++ class inside of Lua.
This is the current way I am looking at solving the issue. It compiles but nothing happens in Lua.
Does anyone know what I am doing wrong, or does anyone have any other suggestions?
Manager.lua
newObject("Object", 1234)
printAll()
Manager.h
#ifndef MANAGER_H
#define MANAGER_H
#include <iostream>
#include <vector>
#include <string>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include "luabind/luabind.hpp"
#include "Object.h"
class Manager
{
private :
lua_State *L;
std::vector<Object> obj;
public :
Manager();
void newObject(std::string t, int nm);
void printAll();
};
#endif
Manager.cpp
#include "Manager.h"
Manager::Manager()
{
luabind::open(L);
luabind::module(L) [
luabind::class_<Manager>("Manager")
.def(luabind::constructor<>())
.def("newObject", &Manager::newObject)
];
luaL_dofile(L, "Manager.lua");
}
void Manager::newObject(std::string t, int nm)
{
if(t == "Object")
{
Object object(nm);
obj.push_back(object);
}
}
void Manager::printAll()
{
for(unsigned int i = 0; i < obj.size(); i++)
std::cout << obj[i].getNum() << std::endl;
}
so that I can call functions on the already created C++ class inside of Lua.
If you use Luabind to create a class, and then provide members of that class, then Luabind will do exactly that. It will expose a class to Lua that has members.
You cannot call a member function in C++ without an object of that class's type. And therefore, when you expose a class and its members through Luabind, you will not be able to call member functions in Lua without an object of that class's type.
Therefore, if you have some global Manager object, the proper way to expose this to Lua is to expose the object itself to Lua. Use Luabind to get the global table, then put a pointer to your Manager object in it. Alternatively, you can pass the Manager object instance as a parameter when you execute the script.
The second method would work something like this:
//Load the script as a Lua chunk.
//This pushes the chunk onto the Lua stack as a function.
int errCode = luaL_loadfile(L, "Manager.lua");
//Check for errors.
//Get the function from the top of the stack as a Luabind object.
luabind::object compiledScript(luabind::from_stack(L, -1));
//Call the function through Luabind, passing the manager as the parameter.
luabind::call_function<void>(compiledScript, this);
//The function is still on the stack from the load call. Pop it.
lua_pop(L, 1);
Your Lua script can get an instance with Lua's varargs mechanism:
local manager = ...
manager:newObject("Object", 1234)
manager:printAll()