Inserting a function with arguments to appendToGlobalCtors - llvm

I want to insert a function call that executes before anything else in the program. I figured the way to do this is to insert to the global constructors with appendToGlobalCtors() in this way:
LLVMContext &C = M.getContext();
Function* FInit = Function::Create(FunctionType::get(Type::getVoidTy(C), false), GlobalValue::ExternalLinkage, INITMEMORY, &M);
appendToGlobalCtors(M, FInit, 0);
This works well if the function has no arguments. But what if the function I need to insert has arguments that I would like to specify? How do I create the function to insert into the global constructors? The function I have returns void. I already know how to use the IRBuilder to create a function call. But the builder takes the arguments in the builder.CreateCall(Func, FuncArgs). How do I do this and append it to the global constructors?
Hope I was clear enough. Let me know if this needs more clarification.
Thanks!

The only way this is possible is when your arguments are constant, obviously. In this case just wrap your call into another function and mark it __attribute__((constructor)):
void foo(int x, int y)
{
...
}
__attribute__((constructor))
void bar()
{
foo(1,2);
}

Related

Pass class function to another class function

sorry for possible duplicates, but I didn't understand the examples and codes snippets I found.
I have a class named "EncoderWrapper" which includes some functions. One of these functions is called "onAfterTouch" and is declared in the "EncoderWrapper.h" file.
void onAfterTouch(byte channel, byte pressure);
The functions will become a callback for another class function of a library I use
inline void setHandleAfterTouch(void (*fptr)(uint8_t channel, uint8_t pressure)) {
usb_midi_handleAfterTouch = fptr;
};
Note: I'm totally new to C++, so I want to say sorry if I'm doing some "no-gos" or mixing up some terms.
The question is: How can I pass my class function (member function?) to that "setHandleAfterTouch" function of the library?
This won't work:
void EncoderWrapper::attachMIDIEvents()
{
usbMIDI.setHandleAfterTouch(&EncoderWrapper::onAfterTouch);
}
... my IDE says
no matching function for call usb_midi_class:setHandleAfterTouch(void (EncoderWrapper::*)(byte, byte))
I've also tried
usbMIDI.setHandleAfterTouch((&this->onAfterTouch));
But this won't work ... and I don't get the approach on that.
Every Help is very appreciated ;-)
Function pointer and member function pointer have different types. You can it for yourself:
struct Test {
void fun();
};
int main() {
void(*ptr)() = &Test::fun; // error!
}
Instead, member function pointer need this syntax:
void(Test::*fun)() = &Test::fun; // works!
Why you ask? Because member function need an instance to be called with. And calling that function have a special syntax too:
Test t;
(t.*funptr)();
To accept member function pointer, you'll need to change your code to this:
inline void setHandleAfterTouch(void(EncodeWrapper::*fptr)(uint8_t, uint8_t)) {
usb_midi_handleAfterTouch = fptr;
};
Since it's rather limiting accepting only the functions from one class, I recommend using std::function:
inline void setHandleAfterTouch(std::function<void(uint8_t, uint8_t)> fptr) {
usb_midi_handleAfterTouch = std::move(fptr);
};
This will allow you to send lambda with captures, and call your member function insode it:
// we capture this to use member function inside
// v---
usbMIDI.setHandleAfterTouch([this](uint8_t, channel, uint8_t pressure) {
onAfterTouch(channel, pressure);
});
It seems you can't change, and by looking quickly at the API, it doesn't seem you have access to a state object.
In that case, if you want to use your member function, you need to introduce a global state:
// global variable
EncodeWrapper* encode = nullptr;
// in your function that sets the handle
encode = this; // v--- No capture makes it convertible to a function pointer
usbMIDI.setHandleAfterTouch([](uint8_t, channel, uint8_t pressure) {
encode->onAfterTouch(channel, pressure);
});
Another solution would be to make onAfterTouch function static. If it's static, it's pointer is not a member function pointer, but a normal function pointer.

How can I call a function using parameter list in c++?

I have a unchangeable function like
void foo(int a, const char* b, int c)
{
}
and I want to call this function as follows:
void main()
{
paramList.add(1);//adding int
paramList.add("hello world"); //adding string
paramList.add(3);//adding int
foo(paramlist);
}
How can I call foo function as in example?
You can create an overloaded function that takes the paramlist object, and extracts the items to call the proper foo function with its actual arguments.
You cannot. No matter what tricks you try to pull off in the calling code, the function must be passed three arguments.
What you probably have in mind does exist in C++ and is known as the Named Parameter Idiom. But it would require changing the function which you are describing as "unchangeable."
P.S.: void main is not legal C++. Make it int main.

Send void type defined function pointer as argument to be called

I don't know if what I am trying to do is possible but it would be grate to be. It will really prove that C++ is a strong language.
So, I have a DLL and an EXE that uses a function exported by the DLL. That function takes an argument which is, or must be a pointer to another function, and executes it. Something like this:
extern void RunFunction(void (*FunctionPonter)()) {
(*FunctionPonter)();
}
and I call it like this:
RunFunction(&FunctionToExecute);
The function sent as an argument will not have arguments, just a void function.
So, all this works, as it is presented here. Now, I would like to go further and define (*void)() as, for example, Action.
typedef (*void)() Action;
Action FunctionToExecute() {
// My code. This function won't return results - void
}
and I would like to send the pointer to the function in my DLL like this:
// This is how it would be declared now in the DLL
extern void RunFunction(void (ACTION) {
(*FunctionPonter)();
}
// and this is how I would like to use it
RunFunction(FunctionToExecute);
I am using VC2010 and I don't know how could I do that, if it is possible. Thanks for your ideas, explanations and help!
Firstly, the proper syntax for function type typedef is
typedef void (*Action)();
Secondly, typedef-name for function type can be used to declare functions of that type, but they cannot be used to define such functions. I.e. if FunctionToExecute is the function you wat to execute through the pointer, then it has to be defined as
void FunctionToExecute() {
/* whatever */
}
The calling function would be defined as
void RunFunction(ACTION p) {
p();
}
And the call to it would look as follows
RunFunction(FunctionToExecute);
That's it. Unary * and & operators are optional with function pointers.
Ok, if I understand your question correctly, you're looking for a way to only allow certain functions to be passed as arguments to your DLL function.
Using a typedef won't work, as that just creates an alias; Action and void (*)() are indistinguishable to the compiler in your code. Instead, you'll have to create a brand new type. In C++, you should strongly consider using a functor:
// Abstract functor
struct Action {
virtual void operator() () const = 0;
};
// The DLL function
void RunFunction(const Action &action) {
action();
}
// Define your function as a derived functor
struct FunctionToExecute : Action {
void operator() () const { std::cout << "Hello\n"; }
};
// Run a function
RunFunction(FunctionToExecute());
Demo: http://ideone.com/5pl23.

How can I make a bool reference argument defaulted?

In C++, is it possible to make a bool & argument of a function optional?
void foo(bool &argument = /* What goes here? */);
In my function foo, if the caller does not care about the result put into argument, I'd like the compiler to give a dummy location by default. Otherwise, callers who do not care must do this:
bool ignored;
foo(ignored);
Make another function
void foo(){
bool b=true;
foo(b);
}
The only way is to pass a global variable :
bool someArgument = false;
void foo(bool &argument = someArgument );
Ideally you should be using a function overload instead of trying to work around the system. Although there are legitimate ways to achieve this like the one #VJovic mentioned. With function overloads you can make other parameters optional too if ever you need to add more.
A non-const reference argument means your function intends to modify the object being passed. If you know which object you want that to be by default, then just use it as the default argument.
If you do not intend to modify the bool being passed in, then you should declare the function to take bool argument (i.e. not a reference) or const bool &argument. In either case you can provide a constant default value of true or false.
You can do it. But it is very ugly and messes up data locality:
static bool result__ = false;
static void foo(bool & result = result__)
{
result = true;
}
int main()
{
bool v;
foo();
foo(v);
return v ? 0 : 1;
}
Since C++ supports function overloading, use #QuentinUK's solution.

passing functor as function pointer

I'm trying to use a C library in a C++ app and have found my self in the following situation (I know my C, but I'm fairly new to C++). On the C side I have a collection of functions that takes a function pointer as their argument. On the C++ side I have objects with a functor which has the same signature as the function pointer needed by the C function. Is there any way to use the C++ functor as a function pointer to pass to the C function?
You cannot directly pass a pointer to a C++ functor object as a function pointer to C code
(or even to C++ code).
Additionally, to portably pass a callback to C code it needs to be at least declared
as an extern "C" non-member function.
At least, because some APIs require specific function call conventions and thus
additional declaration modifiers.
In many environments C and C++ have the same calling conventions and differ only
in name mangling, so any global function or static member will work.
But you still need to wrap the call to operator() in a normal function.
If your functor has no state (it is an object just to satisfy some formal
requirements etc):
class MyFunctor {
// no state
public:
MyFunctor();
int operator()(SomeType &param) const;
}
you can write a normal extern "C" function which creates the functor and executes its
operator().
extern "C" int MyFunctorInC(SomeType *param)
{
static MyFunctor my_functor;
return my_functor(*param);
}
If your functor has state, eg:
class MyFunctor {
// Some fields here;
public:
MyFunctor(/* some parameters to set state */);
int operator()(SomeType &param) const;
// + some methods to retrieve result.
}
and the C callback function takes some kind of user state parameter (usually void *):
void MyAlgorithmInC(SomeType *arr,
int (*fun)(SomeType *, void *),
void *user_state);
you can write a normal extern "C" function which casts its state parameter to
your functor object:
extern "C" int MyFunctorInC(SomeType *param, void *user_state)
{
MyFunctor *my_functor = (MyFunctor *)user_state;
return (*my_functor)(*param);
}
and use it like this:
MyFunctor my_functor(/* setup parameters */);
MyAlgorithmInC(input_data, MyFunctorInC, &my_functor);
Otherwise the only normal way to do it
(normal as in "without generating machine code at runtime" etc.)
is to use some static (global) or thread local storage to pass the functor
to an extern "C" function.
This limits what you can do with your code and is ugly but will work.
I found this "gem" using google. Apparently possible but I sure wouldn't recommend it. Direct link to example source code.
No, of course. The signature of your C function take an argument as function.
void f(void (*func)())
{
func(); // Only void f1(), void F2(), ....
}
All tricks with functors are used by template functions:
template<class Func>
void f (Func func)
{
func(); // Any functor
}
A C callback function written in C++ must be declared as an extern "C" function - so using a functor directly is out. You'll need to write some sort of wrapper function to use as that callback and have that wrapper call the functor. Of course, the callback protocol will need to have some way of passing context to the function so it can get to the functor, or the task becomes quite tricky. Most callback schemes have a way to pass context, but I've worked with some brain-dead ones that don't.
See this answer for some more details (and look in the comments for anecdotal evidence that the callback must be extern "C" and not just a static member function):
C++ Using Class Method as a Function Pointer Type
I don't think you can: operator() in a function object is really a member function, and C doesn't know anything about those.
What you should be able to use are free C++ functions, or static functions of classes.
GCC allows you to convert member function pointers to plain function pointers (the first argument of the function called by the plain function pointer then is this).
Check out the respective link in the manual.
This requires the -Wno-pmf-conversions flag in order to silence the respective warning for the decidedly non-standard feature. Very convenient for interfacing C style libraries with C++ style programming. When the member function pointer is a constant, this does not even need to generate any code at all: the API would use that argument order anyway.
If you already have a functor, flattening the functor in that manner will likely mean flattening its operator(), giving you a function that has to be called with a functor class pointer itself as its first argument. Which does not necessarily help all that much but at least has C linkage.
But at least when you are not going through functors this is helpful and provides a no-nonsense C linkage replacement for std::mem_fn from <functional>.
It depends if this is a static or instance method, if it is static then you can pass through the function as className::functionName, if it is an instance method it is fair more complicated, because you obviously need to tie to a certain instance but can't do it in the same way as you would with delegates in C# etc.
The best way I've found of doing this is to create a holding class which is instantiated with the instance of the object as well as the function pointer, the holding class can then invoke the function directly.
I would say no, because a C++ functor has an overloaded operator () which is a member function, and would thus require a member function pointer. This is a totally different data type than a normal C function pointer, since it cannot be invoked without an instance of the class. You'd need to pass a normal function or a static member function to the C library. Since an overloaded () operator can't be static, you can't do it. You'd need to pass the C-library a normal, non-member function or static member function, from which you can then invoke the C++ functor.
Hm, maybe you could write a free template function that wraps around your function-objects. If they all have the same signature, this should work. Like this (not tested):
template<class T>
int function_wrapper(int a, int b) {
T function_object_instance;
return funcion_object_instance( a, b );
}
This would do for all function that take two ints and return an int.
Many C APIs that take function pointer callbacks have a void* parameter for user state. If you've got one of those, you're in luck - you can use an exterm C function that treats the user data as some sort of reference or key to lookup the functor, then execute it.
Otherwise, no.
With C++11, you can use std::bind to solve the problem
#include <stdio.h>
#include <functional>
class aClass
{
public:
int i = 5;
aClass(int i_) : i(i_) {}
void operator()(int a, int b) {
i = i + 1;
printf ("%d + %d = %d i = %d\n", a, b, a + b + i, i);
}
};
void test (int a, int b)
{
printf ("%d - %d = %d\n", a, b, a - b);
}
template <class op>
void function1 (op function)
{
function (1, 1);
}
int
main (int argc, const char *argv[])
{
aClass a(1);
// function1 (a); // this is the wrong way of using it
using namespace std::placeholders;
std::function<void(int,int)> callback;
callback = std::bind(&aClass::operator(), &a, _1, _2);
function1 (callback);
function1 (callback);
function1 (test);
function1 (test);
return 0;
}