I have a very simple function in C and its pointer gets passed into Swift.
void callback() {
NSLog(#"such pointer…");
}
How can it be invoke in Swift using ONLY the pointer? This is NOT about simply invoking it – it works fine when invoked directly. Tried the following and different variations with signature casting, but it always crashes:
let pointer: UnsafePointer<#convention(c)() -> ()> = UnsafePointer(bitPattern: …)
let callback: #convention(c)() -> () = pointer.memory
Swift.print(callback) // (Function)
callback() // Handling crash with signal 11...
Tried defining Callback type with typedef void(*Callback)(); – same thing:
let pointer: UnsafePointer<Callback> = UnsafePointer(bitPattern: …)
let callback: Callback = pointer.memory
Swift.print(callback) // (Function)
callback() // Handling crash with signal 11...
To check that it actually works and points to the right address I have another Objective-C function, which works as expected when invoked from Swift with the callback pointer.
void invokeCallback(uintptr_t callback) {
((void (*)()) callback)(); // such pointer…
}
The same approach as in Swift: How to call a C function loaded from a dylib should work here.
Example for Swift 3 (assuming that funcPtr is a
UnsafeRawPointer containing the function's address):
// Define function type:
typealias callbackFunc = #convention(c) () -> Void
// Convert pointer to function type:
let callback = unsafeBitCast(funcPtr, to: callbackFunc.self)
// Call function:
callback()
Of course the type alias must match the actual function signature,
and the function needs to be a "pure" C function (not an Objective-C
method).
Related
I'm trying to implement a Python-like function decorator in C using function pointers but I'm getting weird segmentation fault error.
Idea is that we have a decorator function which has inner function wrapper. Decorator then takes some_function as an argument, puts it inside the wrapper along with additional code and returns the wrapper function.
Very simple function decorator in Python:
def decorator(f):
def wrapper():
#do something before
f()
#do something after
return wrapper
def some_func():
print('Hello')
some_func = decorator(some_func)
I know that Python, unlike C, treats functions as first class objects but I'm wondering if the same sort of functionality can be emulated in C by using function pointers.
I tried this
void* do_twice(void (*func)())
{
auto void wrapper()
{
func();
func();
}
return &wrapper;
}
void some_func()
{ printf("Hello\n"); }
int main()
{
void (*fun_ptr)() = &some_func;
fun_ptr = decorator(fun_ptr);
fun_ptr();
return 0;
}
Output
Hello
Segmentation fault
Now here is the funny bit. If I declare a variable inside wrapper like this:
auto void wrapper()
{
int blah=5;
func();
func();
}
Then segmentation fault is fixed. Can someone explain why is this so? Apparently I'm doing something wrong with the pointers and code is very unstable - seemingly unrelated additions to the main function will cause segmentation fault to pop again.
Do you allow me to have an excursion to C++? In this language, there are functor objects, these are kind of structs that can be called like a function:
struct Wrapper
{
/* this is what allows the struct to be called like a function: */
void operator()(/* can define arbitrary parameters here */)
{ /* some implementation */ }
};
In other words, this would allow you to write code like:
Wrapper w; // actually, C++ does more here than C, but that's out of
// scope of this question...
w(); // possible due to the operator() defined above
OK, now let's extend that a bit:
struct Wrapper
{
void(*m_f)(void); /* !!! */
void operator()(void) /* don't want any parameters... */
{
printf("before\n");
m_f();
printf("after\n");
}
};
Don't want to go any deeper, a C++ developer would now deal with accessibility (such that the member m_f can only be used inside the class) and would provide a so-called constructor (for initialising m_f member appropriately). With all that, the final C++ code using the wrapper class might look like:
Wrapper decorate(void(*f)(void))
{
return Wrapper(f); // the fore-mentioned constructor gets called
}
void test(void) { /* do something */ }
void demo(void)
{
Wrapper w = decorate(&test);
w();
}
Why that excursion? Well, have a close look at one specific line:
void(*m_f)(void);
Yes, there is a member variable! Python actually does something similar internally.
The 'problem' with C is that you cannot define your own function call operators. There's only the native one. So the big question is: Where to store the function pointer?
You could have a struct, storing the function pointer (analogously to the C++ solution), and pass that one to your own function emulating the function call operator. Actually, the C++ solution doesn't do anything else either, solely that all this is hidden behind syntactic sugar!
An equivalent C solution might look like this:
struct Wrapper
{
void(*m_f)(void);
};
void executeDecorated(Wrapper w)
{
printf("before\n");
w.m_f();
printf("after\n");
}
void demo(void)
{
Wrapper w = { &someFunction };
executeDecorated(w);
/* do whatever else ... */
executeDecorated(w);
}
This is probably the closest you can get in C (apart from that you might perhaps find better names).
If having a separate struct to store a function pointer brings you sufficient benefit or if you just want to pass the function pointer directly (executeDecorated(&someFunction), assuming the function was adjusted appropriately) is up to you to decide...
Suppose I have a print Function which takes a void* as an argument:
Print(void *instance)
How can I Set the member of a struct to this method?
struct Foo
{
void(*Print)(); //this does not match to Print above!
//void(*Print)(void* Instance); //This would but I cannot change this
}
So how would I have to change this method:
void Init()
{
struct Foo* k = malloc(sizeof(Foo));
Foo->Print = &Print(k); //does not work?!
//Foo->Pring = &Print; //would work if types were the same
}
I want to set a function pointer inside a struct with a Fixed argument.
Basically this is a way to implement object oriented code in ANSI-C.
The source project is this: Object Orientation in C?!
This would be about changing this piece of C Code:
String* r = New_String("Hello");
r->Free(r); //this works
r->Free(); //this is how it should be!
So that the instance does not have to be passed to the methods themselfes.
Summarized: Goal is to get the Foo instance inside Print called like Foo->Print();
With:
Foo->Print = &Print(k);
you are assigning a function pointer and you are "calling" the function with a parameter. That is wrong. What you can do is:
Foo->Print = Print;
Foo->Print = (void(*)())Print; // if compiler complains, use a cast
Because Print is a function, the compiler will use its address when assigning it to the function pointer field of the struct. But because your Print function is incompatible with the Print field, you must use a cast to silence the compiler. Your Print function is casted to a "function that can take any number of parameters". The casting is safe here as long as you call it with at least one parameter. Only do this casting when you know what you are doing, or undefined behavior will follow.
Once the function pointer is assigned, you can now call it with your parameter:
Foo->Print(k);
I have the following C function
struct answer* create(struct callbacks *callbacks);
I need to create a struct of function pointers and call this function from Swift
What I have so far is:
func aa(state: CInt, user_data: UnsafeMutablePointer<Void>) {}
func bb(state: CInt, user_data: UnsafeMutablePointer<Void>) {}
struct CallbacksStruct {
let on_aa = aa
let on_bb = bb
}
and I try to call the function like this:
var callbackStruct = CallbacksStruct()
let ans = create(&callbackStruct)
but, without any success
Is it even possible in Swift ?
Yes, it should be possible. In Swift 2, one can send a Swift closure as a parameter to C, when C expects a function pointer. In your case, you have wrapped it in a struct, so an addition of '#convention(c)' to explicitly state that it's C, might help.
see examples here
new-conventionc-in-swift-2-how-can-i-use-it
I am trying to use a C API in Swift that requires me to pass a callback to a function using variadic arguments, i.e.:
extern GEOSContextHandle_t GEOS_DLL initGEOS_r(
GEOSMessageHandler notice_function,
GEOSMessageHandler error_function);
where GEOSMessageHandler is defined as:
typedef void (*GEOSMessageHandler)(const char *fmt, ...);
How should I handle this? I tried to implement an Objective-C class with two class methods defined as follows:
#interface HumboldtCallback : NSObject
+(void)noticeCallback:(const char *)args, ... NS_REQUIRES_NIL_TERMINATION;
+(void)errorCallback:(const char *)args, ... NS_REQUIRES_NIL_TERMINATION;
#end
but Swift does not let me access them. If I define the arguments as void* I can access them from Swift:
var GEOS_HANDLE: COpaquePointer {
let noticeCallbackPointer = HumboldtCallback.noticeCallback;
let errorCallbackPointer = HumboldtCallback.errorCallback;
return initGEOS_r(noticeCallbackPointer, errorCallbackPointer)
}
but the compiler still isn't happy:
Cannot invoke 'initGEOS_r' with an argument list of type '((UnsafeMutablePointer<Void>) -> Void, (UnsafeMutablePointer<Void>) -> Void)'
Should I somehow cast the pointer to the callback function before passing it as a parameter to the init function?
You need to write a C function instead of an objective C method. Unfortunately Swift will convert these into Swift Closure. However you can write a function/method in objective C to return your function pointer. This will stop Swift being able to convert the function to a closure. i.e in your objectiveC header:
void myCallback (const char *fmt, ...);
GEOSContextHandle_t getMyCallback ();
then in the class implement getMyCallback like this:
GEOSContextHandle_t getMyCallback () {
return myCallback;
}
and implement your callback function. In Swift you'll end up with:
initGEOS_r(getMyCallback(), ...)
I believe that you can do this with a plain C header and .c file rather than using an object.
calling a function by a pointer which hold the address of the function is generating error
code:
p=GetProcAddress(h,"installhook");//p is a pointer that holds the address returned from getprocaddress() function
(*p)(); //using this pointer making a call to installhook function
but the code is generating error wher i am making a call by (*p)(); it says term does not evaluate to a function.
how doi overcome with this?is there any other way making a call to the function using pointer?
You need to cast the return value of GetProcAddress to the correct function type. For example:
typedef void (*FuncPtr)(); //assuming a function like void f()
FuncPtr p;
p = (FuncPtr) GetProcAddress(h, "funcName");
if (p)
p();
else
printf("Function not found\n");
Verify p is declared like this:
void (*p)(void);
and that the type of the return value of GetProcAddress is the same.