Extracting a parameter from a function passed as parameter - c++

I have a following function:
void Class1::MainThreadFunction(const __int64 param) {
if(GetCurrentThreadId() != System::MainThreadID) {
RunInMainThread(MainThreadFunction, param);
return;
}
//...
}
void Class2::RunInMainThread(void(__closure* FuncToCall)(const __int64 ParToExtract),
const __int64 fP1) {
struct {
__int64 P1;
void(__closure* F)(const __int64);
void __fastcall FTC() { F(P1); }
} Args = {fP1, FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
So what I am attempting to do is to extract the first parameter in FuncToCall which is named ParToExtract above to be used for initializing the Args structure. In other words the P1 in the struct should receive the const __int64 from the passed function which is named as ParToExtract.
The above works but I currently as a workaround pass the parameter as fP1 which I use to initialize P1 but there surely must be a better way to do this.
Additional bonus would be to have the variable number of function parameters in RunInMainThread (but I have for the moment to avoid C++11 <functional>).
Please no lambda-based (or C++11 features) - this is another thing I cannot yet use for the moment.

What you already have is the correct (and only) way to approach this situation in C++Builder's "classic" (pre-C++11) compilers.
In order to support a variable number of parameters, you will have to use multiple overloads, there is no other option (without delving into low-level inline assembly to setup call stacks manually, but even then it may not work correctly across thread boundaries), eg:
void Class1::MainThreadFunction()
{
if (GetCurrentThreadId() != System::MainThreadID)
{
RunInMainThread(MainThreadFunction);
return;
}
//...
}
void Class1::MainThreadFunction(const __int64 param)
{
if(GetCurrentThreadId() != System::MainThreadID)
{
RunInMainThread(MainThreadFunction, param);
return;
}
//...
}
// and so on as needed ...
template<typename FuncType>
void Class2::RunInMainThread(FuncType FuncToCall)
{
struct {
FuncType F;
void __fastcall FTC() { F(); }
} Args = {FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
template<typename FuncType, typename ParamType>
void Class2::RunInMainThread(FuncType FuncToCall, const ParamType param)
{
struct {
const ParamType &P;
FuncType F;
void __fastcall FTC() { F(P); }
} Args = {param, FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
template<typename FuncType, typename ParamType1, typename ParamType2>
void Class2::RunInMainThread(FuncType FuncToCall, const ParamType1 param1, const ParamType2 param2)
{
struct {
const ParamType1 &P1;
const ParamType2 &P2;
FuncType F;
void __fastcall FTC() { F(P1, P2); }
} Args = {param1, param2, FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
// and so on as needed...
If you look through various RTL header files, such as sysvari.h and utilcls.h, using overloads is how Borland itself approaches the issue of variable number of parameters in several of its own APIs, sometimes upwards of 30+ parameters, which is more than enough to handle most user code.

The signature for the method called by TThread::Synchronize() must match the TThreadMethod type:
void __fastcall (__closure *TThreadMethod)(void);
So you can't pass parameters through it directly. Instead of going through a proxy function, use a lambda:
void MainThreadFunction(int64_t param) {
if(GetCurrentThreadId() != System::MainThreadID)
TThread::Synchronize(nullptr, [&param]{ MainThreadFunction(param); } );
//...
}
In order to have a variable number of parameters, you could make it a function template:
template< class... Args >
void MainThreadFunction(Args&&... args) {
if(GetCurrentThreadId() != System::MainThreadID)
TThread::Synchronize(nullptr, [&args...] {
MainThreadFunction(std::forward<Args>(args)...);
}
);
//...
}
When using a classic (pre C++11) compiler, you'd usually use a class private variable to carry the information.

Related

Performant and Elegant Dispatching on Type for Scripting Language Implementation

I am working in the implementation of a scripting system where values are passed around as void* and an enum indicating the type.
enum class ValueType
{
Bool,
Float,
Int,
// many more types...
};
I need a workflow for implementing APIs like the following. These APIs must be as performant as possible (switch statement rather than virtual call).
void Print(ValueType type, void* value);
bool Equals(ValueType type, void* value1, void* value2);
// etc...
I would settle for the kludgy solution I have right now, but it is extra cumbersome given that I have to produce specific sets of APIs for different subsystems. Any ideas would be greatly appreciated.
Current solution (lambdas and auto are not allowed in the code base I'm working in, but I'd still be interested in seeing solutions that use those features)
// Per-type implementations
template <typename T>
class SubsystemFunctions
{
public:
void Print(void* value)
{
std::cout << *static_cast<T*>(value) << std::endl;
}
bool Equals(void* value1, void* value2)
{
return *static_cast<T*>(value1) == *static_cast<T*>(value2);
}
};
// API and gory dispatching details
class SubsystemAPI
{
public:
static void Print(ValueType type, void* value)
{
DispatchOnType(type, PrintDispatcher(), value);
}
static bool Equals(ValueType type, void* value1, void* value2)
{
bool result;
DispatchOnType(type, EqualsDispatcher(), value1, value2, &result);
return result;
}
private:
struct PrintDispatcher
{
template <typename FunctionsT>
void operator()(FunctionsT&& functions, void* value)
{
functions.Print(value);
}
};
struct EqualsDispatcher
{
template <typename FunctionsT>
void operator()(FunctionsT&& functions, void* value1, void* value2, bool* result)
{
*result = functions.Equals(value1, value2);
}
};
private:
template <typename DispatcherT, typename... ArgsT>
static void DispatchOnType(ValueType type, DispatcherT&& dispatcher, ArgsT&&... args)
{
switch (type)
{
case ValueType::Bool:
dispatcher(SubsystemFunctions<bool>(), std::forward<ArgsT>(args)...);
break;
case ValueType::Float:
dispatcher(SubsystemFunctions<float>(), std::forward<ArgsT>(args)...);
break;
case ValueType::Int:
dispatcher(SubsystemFunctions<int>(), std::forward<ArgsT>(args)...);
break;
// etc...
}
}
};

Crash in shared_ptr destructor in templated function

In my 32-bit VS2015 application, I have a templated function that accesses functions of a library (BTK). Depending on the type of this function, a specific overload of a function of this library is called.
This works fine, but recently I'm using this same code and library (same binaries and code) in another (also VS2015 32-bit) application, and it segfaults/access violation in the destructor of shared_ptr. To be precise, it crashes at the (interlocked) decrement of the use count.
void _Decref()
{ // decrement use count
if (_MT_DECR(_Uses) == 0) // BOOM
{ // destroy managed resource, decrement weak reference count
_Destroy();
_Decwref();
}
}
Now comes the interesting part, when I replace my templated function with a non-templated version, it works fine..
So, if I replace this:
template<class T>
bool SetParameters(const std::string& group, const std::string& param, const std::vector<T>& values, const std::vector<uint8_t>& dims)
{
btk::MetaData::Pointer pParam = GetBtkMetaData(group, param);
if (!pParam)
{
pParam = AddBtkMetaData(group, param);
}
if (!pParam->HasInfo())
{
pParam->SetInfo(btk::MetaDataInfo::New(dims, values));
}
else pParam->GetInfo()->SetValues(dims, values);
return true;
}
with this:
bool C3DFile::SetParameters(const std::string& group, const std::string& param, const std::vector<int16_t>& values, const std::vector<uint8_t>& dims)
{
btk::MetaData::Pointer pParam = GetBtkMetaData(group, param);
if (!pParam)
{
pParam = AddBtkMetaData(group, param);
}
if (!pParam->HasInfo())
{
pParam->SetInfo(btk::MetaDataInfo::New(dims, values));
}
else pParam->GetInfo()->SetValues(dims, values);
return true;
}
It works fine... Apparantly, the template-instantiation has some effect on the shared pointers. I have three questions:
What kind of effect could templates have on this? I can imagine that the code instantiation could have some effect, but I'm not sure.
Why would the templated version work, with the same binaries etc, in one 32-bit VS2015 app, but not in the other? (Where I need to resort to non-templated functions)
Which compiler/linker options could be relevant? I checked the compiler and linker options, but couldn't find a relevant difference.
Any help would be appreciated.
Ben
What kind of effect could templates have on this? I can imagine that the code instantiation could have some effect, but I'm not sure.
ADL: the template method will use ADL to find the dependent methods (in your case btk::MetaDataInfo::New(dims, values)), whereas the non template only considers visible declarations, so the possible difference.
Example:
struct A{};
void fooT(const void*) { std::cout << "void*\n"; }
template <typename T> void barT(const T* p) { fooT(p); }
void fooT(const A*) { std::cout << "A*\n"; }
void foo(const void*) { std::cout << "void*\n"; }
void bar(const A* p) { foo(p); }
void foo(const A*) { std::cout << "A*\n"; }
int main()
{
A a{};
barT(&a); // fooT(const A*) -> A*
bar(&a); // foo(const void*) -> void*
}
Demo

C++ member function pointer with different arguments - or is this bad anyway?

Even though I fear that you will tell me that this topic was covered several time, I dare to ask it, since I was not able to generate a solution. Probably I was just looking for the wrong thing...
Assume that I have a function which receives a "mode" from some external function. Depending on the mode, the function will call different member functions of the same object. This works well for me with member function without any argument, but I did not find out how to extend it to members with arguments. In the real world application, the arguments are not int/float but a more complex classes and the call is nested inside different loops, so I would need to put switch statements several times which I consider ugly.
Question A: Is it possible to easily add support for member functions with arguments based on the existing design? If yes, how does one do that? If possible without external libraries...
Question B: Is this a completely wrong/bad approach? How would I do it better?
Thanks a lot for your help and explanations.
Chris
header excerpt:
typedef void (Object::*memberFunction)();
class Object
{
void memberFnNoArg();
void memberFnWithIntArg(int arg);
void memberFnWithFloatArg(float arg);
}
cpp excerpt:
void function()
{
int mode = getModeFromSomewhere();
int intArg = 33;
float floatArg = 66.6;
switch(mode)
{
case 1:
process(&Object::memberFnNoArg);
break;
case 2:
process(&Object::memberFnWithIntArg, ???); // how can I pass arg?
break;
case 3:
process(&Object::memberFnWithFlaotArg, ???); // how can I pass arg?
break;
default:
// do nothing;
}
}
void process(Object::memberFunction func)
{
Object object;
// loops, called several times, ...
(object.*func)(); // how do I handle different arguments?
}
Wrapping the algorithm in a functor is the right approach, and std::function is a nice functor provided by the Standard library.
But using boost::bind or even std::bind, as suggested by Tomek, is really ugly IMO, and rapidly gets out of control when binding multiple arguments.
If you have a recent compiler you can use a lambda instead, which makes Tomek's example look like:
std::function<void(Object*)> f =
[](Object* const that){ that->memberFnNoArg(); };
int int_value = 22;
std::function<void(Object*)> f2 =
[int_value](Object* const that){ that->memberFnIntArg(int_value); };
Object o;
f(&o);
f2(&o);
There are a few characters to set up the lambda, but the member access syntax is extremely natural and it's obvious how you make changes.
Of course, you can make the parameter a reference to the object if you really want, but I prefer pointers here.
Have a look at std::function and std::bind, they seem to fit perfectly what you need.
EDIT:
std::function<void(Object &)> f = &Object::memberFnNoArg;
std::function<void(Object &)> f2 = std::bind(&Object::memberFnWithIntArg, _1, 22);
Object o;
f(o);
f2(o);
should work out of a box as far as I remember.
Is this what you need?
You could use a varadic template function:
template <typename... Args>
void process(void (Object::*func)(Args...),Args... args)
{
Object object;
// loops, called several times, ...
(object.*func)(args...);
}
Here is a full example:
#include <iostream>
struct Object
{
void memberFnNoArg()
{
std::cout << "Object::memberFnNoArg()\n";
}
void memberFnWithIntArg(int arg)
{
std::cout << "Object::memberFnWithIntArg(" << arg << ")\n";
}
void memberFnWithFloatArg(float arg)
{
std::cout << "Object::memberFnWithFloatArg(" << arg << ")\n";
}
};
template <typename... Args>
void process(void (Object::*func)(Args...),Args... args)
{
Object object;
// loops, called several times, ...
(object.*func)(args...);
}
int main()
{
process(&Object::memberFnNoArg);
process(&Object::memberFnWithIntArg,5);
process(&Object::memberFnWithFloatArg,2.7F);
return 0;
}
One way I see around this would be to use a variable arguments (pretty much like printf, sprintf does it). (Or maybe with stdc libraries, passing a list of different types.)
The reason is, that the argument list is part of the function pointer type, so you'd essentially need a process function with variable arguments and then the memberFunction probably needs to be one of that type too.
Below is a plain (non member) sample of how to pick up variable arguments (member functions would essentially work the same). See stdarg.h.
typedef void (*var_function)(int typearg, ...);
void print_arg(int typearg, ...)
{
va_list ap;
int i;
va_start(ap, typearg);
if (typearg==1) { // int
int i= va_arg(ap, int);
printf("%d ", i);
}
else
if (typearg==2) { // float
float f= va_arg(ap, float);
printf("%f ", f);
}
else
if (typearg==3) { // char *
char *s= va_arg(ap, char *);
printf("%s ", s);
}
....
va_end(ap);
}
// calling function with different types
int main()
{
print_arg(1, 999);
print_arg(2, 3.1415926);
print_arg(3, "Hello");
....
process(print_arg, 3, "via pointer);
Sounds like packaged_task. Also check out Tomek's suggestion.
Though IRL I'd go ahead asking lots of questions on why you need it in the first place. Possibly your work could be better covered using std::future or other higher level facility,
Can't each function (memberFn**) be a member of argument classes ?
class BaseArg
{
virtual void Fn() = 0;
};
class IntArg : public BaseArg
{
void Fn();
};
class FloatArg : public BaseArg
{
void Fn();
};
void function()
{
int mode = getModeFromSomewhere();
BaseArg* pArg;
if ( mode ... ){
pArg = new IntArg( 33 );
}
else {
pArg = new FloatArg( 66.6 );
}
pArg->Fn(); // Call the right function without a switch
// and without knowing the arguments
}
Same as other answers, but to show for member methods:
#include <iostream>
class Object
{
public:
void memberFnNoArg()
{
std::cout << "Object::memberFnNoArg()\n";
}
void memberFnWithIntArg(int arg)
{
std::cout << "Object::memberFnWithIntArg(" << arg << ")\n";
}
void memberFnWithFloatArg(float arg)
{
std::cout << "Object::memberFnWithFloatArg(" << arg << ")\n";
}
bool memberFnWithBoolReturn(int)
{
return true;
}
template <typename... Args>
void process(void (Object::*func)(Args...),Args... args);
// overload process
template <typename... Args>
bool process(bool (Object::*func)(Args...),Args... args);
};
template <typename... Args>
void process( void (Object::*func)(Args...),class Object* obj,Args... args)
{
(obj->*func)(args...);
}
template <typename... Args>
bool process( bool (Object::*func)(Args...),class Object* obj,Args... args)
{
return ((obj->*func)(args...)) ;
}
int main()
{
Object object;
process(&Object::memberFnNoArg,&object);
process(&Object::memberFnWithIntArg,&object,5);
process(&Object::memberFnWithFloatArg,&object,2.7F);
// overloaded process
printf("%d\n",process(&Object::memberFnWithBoolReturn,&object,1));
return 0;
}

How to execute unary function objects of different parameter type in sequence?

I'm designing a mechanism that will execute a set of unary function objects in sequence. These function objects are assigned during runtime, and the problem is: the parameter type of these function objects are different.
What I want to do is something like this:
class command_sequence {
private:
/* some kind of container */
public:
void add( FUNC_OBJ &func, PARAM val );
void run(void);
};
class check_temperature {
public:
void operator() (int celsius) {
if(celsius > 26) {
cooler.switch_on();
}
}
};
class log_usage {
public:
void operator() (std::string username) {
username.append(" logged in");
syslog(LOG_NOTICE,username.c_str());
}
};
command_sequence sequence;
log_usage logger;
check_temperature checker;
sequence.add(logger, std::string("administrator"));
sequence.add(checker, lobbyMeter.read_temperature());
sequence.add(logger, std::string("lecture"));
sequence.add(checker, classroomMeter.read_temperature());
sequence.run();
If I'm writing C code, I have no choice but callback function pointer that takes void* as parameter. But I'm now working with C++, there should be an elegant way to deal with it.
The best way I can think now is declaring a template class that virtually inherit from a abstract wrapper class :
class command_sequence {
private:
class runner {
public:
virtual void execute(void) = 0;
};
template <class FUNC, typename T> class func_pair : public runner {
private:
FUNC &func;
T param;
public:
func_pair(FUNC &f, const T &t) : func(f),param(t) { }
void execute(void) {
func(param);
}
};
std::vector<runner*> funcQueue;
public:
template <class FUNC, typename T> void add(FUNC &obj, const T &t) {
funcQueue.push_back( new func_pair<FUNC,T>(obj,t) );
}
void run(void) {
std::vector<runner*>::iterator itr=funcQueue.begin();
for(;itr!=funcQueue.end();++itr) {
(*itr)->execute();
delete (*itr);
}
}
};
This approach can fit my needs, but it would allocate and release template_pair for each entry. I've no idea whether this would cause memory fragment, since this procedure will be called quite frequently during the process.
Is there any better way to do this ?
Do you really need to pass a function object and its argument separately? I'd use boost::bind, in this case it could look like the following:
void check_temperature( int celsius )
{
if(celsius > 26) {
cooler.switch_on();
}
};
void log_usage( std::string username )
{
username.append(" logged in");
syslog(LOG_NOTICE,username.c_str());
};
// keep actions
typedef std::vector< boost::function<void()> > func_arr_t;
func_arr_t actions;
actions.push_back( boost::bind( &log_usage, "administrator" ) );
actions.push_back( boost::bind( &check_temperature, lobbyMeter.read_temperature() ) );
actions.push_back( boost::bind( &log_usage, "lecture" ) );
actions.push_back( boost::bind( &check_temperature, classroomMeter.read_temperature() ) );
// run all
for ( func_arr_t::const_iterator it = actions.begin(); it != actions.end(); ++it )
(*it)();
In this case command_sequence will just keep an array of the function objects.
Since it appears that the argument to the unary function is fixed at the time you add it to the sequence, you could make your sequence accept zero-argument function objects using boost::function, then boost::bind the required parameter, e.g.
class command_sequence {
public:
void add( boost::function<void(void)> functor );
};
/* ... as before ... */
log_usage logger;
check_temperature checker;
sequence.add( boost::bind<void>(logger, "administrator") );
sequence.add( boost::bind<void>(checker, lobbymeter.read_temperature()) );
Note that you have to specify <void> as a template parameter to the boost::bind call since it can't deduce the return type of the function object automatically. Alternatively, you can expose a public typedef called result_type in the class definition which avoids this, i.e.
class log_usage
{
public:
typedef void result_type;
void operator() (const std::string& message)
{
// do stuff ...
}
};
/* ... */
sequence.add(boost::bind(logger, "blah")); // will now compile

Function pointer pointing to a function that takes a function pointer

How do I declare a function pointer that points to a function taking the same function pointer as the argument?
I've tried the following without success:
typedef void (*fnptr)(void (*)());
void func(fnptr)
{
/* ... */
}
void func2(fnptr)
{
/* ... */
}
void main()
{
fnptr fn = &func;
func2(fn);
}
Is this possible?
I very much doubt it, but you can get the needed recursion by introducing a struct.
struct Rec;
typedef void (*RecFun)(const Rec&);
struct Rec {
RecFun fun;
};
Example of use:
#include <iostream>
void nothing(const Rec& rec) {}
Rec recNothing = { nothing };
void f(const Rec& rec)
{
std::cout << "f\n";
rec.fun(recNothing);
}
Rec recF = { f };
void g(const Rec& rec)
{
std::cout << "g\n";
rec.fun(recNothing);
}
Rec recG = { g };
int main()
{
recF.fun(recG);
}
Update: As per the suggestions of Chris, Vitus, and Johannes, here are some convenient implicit conversions (as in Herb Sutter's GotW #57):
struct Rec;
typedef void (*RecFun)(const Rec&);
struct Rec {
RecFun fun;
Rec(RecFun fun) : fun(fun) {}
operator RecFun() const { return fun; }
};
Alas, it cannot be done. It would be nice if you could use typename to forward declare a typedef; something like:
typename fnptr;
typedef (*fnptr)(fnptr);
but that does not work, because typename is restricted to a few specific template uses
The easiest way is to just typedef both. A function pointer is a parameter just like any other type:
typedef (* InnerFunctionPtr)(void);
typedef (* OuterFunctionPtr)(InnerFunctionPtr);
Edit: Folks have pointed out you mean both to be the same type. In that case, it's not possible, as the type would be recursive. It's impossible to create a complete type specification (the type of the function's parameter is never completely specified, ergo...)
it is possible in this way:
typedef void (*fnptr)(void (*)());
fnptr fn1,fn2;
void func(fn1)
{
/* ... */
}
void func2(fn2)
{
/* ... */
}
void main()
{
fnptr fn = &func;
func2(fn);
}
You can also defeat the type system by pretending that the function takes some other function pointer type, and then casting it when you pass something to the function and inside the function to get the original type back.
Not recommended obviously, but just putting it out there.
typedef void (*fnptr)(void (*)());
void func(void (*x)())
{
fnptr f = (fnptr)x;
/* ... */
}
void func2(void (*x)())
{
fnptr f = (fnptr)x;
/* ... */
}
void main()
{
fnptr fn = &func;
func2((void (*)())fn);
}