How to assign function to Rebol struct member - ffi

I first define a function ADD:
add: func [ a [integer!] b [integer!] ] [a + b]
Then a struct:
s: make struct! [
sadd [ function! ]
] add
But Rebol struct does not support the FUNCTION! datatype. How can I assign a function to a Rebol struct?

Callbacks are an alpha feature of Rebol2. See Carl's article for documentation.
Essentially, if you have a dll such as test-lib.dll where the test function takes two integers and returns them again unchanged
extern "C"
MYDLL_API int test(int a, int b, int (*pFunc)(int, int))
{
int result = pFunc(a, b);
return result;
}
you would write the calling function from Rebol like this
test: make routine! [
a [int]
b [int]
c [callback [int int return: [int]]]
return: [int]
] test-lib "test"
So, this test function takes two integers as parameters and a third parameter which is a Rebol function to be used as a callback. The callback in the routine! is a keyword. The block specification is automatically turned into a structure!
The callback function is written like this which takes the two integers returned by the library call, adds them, and returns them.
add-it: func [a b][return a + b]
And it's then used like this
>> test 1 2 :add-it
== 3

Related

When and why should I use void as the return type of a function in C?

I'm currently practising C and learning pointers and arrays. I watched a tutorial where the instructor changed the function from int aFunction() to void aFunction(). Of course, he didn't say why — that's why I'm here. So I'm wondering: when and why should someone use void as the return type for a function.
In C, you have to tell the compiler what are each of the types of the variables you declare. That is why you have things like int and char*.
And functions’ return values are no different. Compiler has to know what each of your functions return types are to work properly. Now if you have a function like add(int a, int b) typically you would want its return type to be of integer, that is why you would define it as
int add(int a, int b)
{
return a+b;
}
Now consider you have a function that doesn’t return anything at all, now you need to tell your compiler that this function returns nothing. That is why void is used. You use void when the function does something but in the end doesn’t need to return any value to the program it was called from. Like this one:
void printAdd(int a, int b)
{
printf(“a + b = %d”, a+b);
}
We are doing a bunch of stuff here but the result from the addition is not returned or stored but rather printed to the screen.
You can use the first function add() like this:
int abc = add(5, 7);
// abc is 12
while you can only use the second function like
printAdd(5, 7);
// you cannot store the value because nothing is returned.
// 5 + 7 = 12 is printed to the screen
The token(s) that precedes the function name in the function declaration is the type of the value that the function returns. In this case there is just one token, but type names may consist of multiple tokens. When you want to return an integer object, you can specify the return type to be int. When the function won't return anything, you use void return type.

How can I implement a function lookup table in C?

Say I had a program where the user could select a number between 0-10. Each number would then correspond to the calling of a certain function. In Python, I know I could just create an array of function names, index into it with the selected option, and then call the function. How would I implement this in C? Or is it even possible?
Here is an example how to do it. Please note that all functions must have the same signature, but of course you can change that from my funptr type to for example a function that has void return or takes a char and not two ints.
// Declare the type of function pointers.
// Here a function that takes two ints and returns an int.
typedef int (*funptr)(int, int);
// These are the two functions that shall be callable.
int f1(int a, int b) { return a + b; }
int f2(int a, int b) { return a - b; }
// The array with all the functions.
funptr functions[] = {
f1,
f2,
};
// The caller.
int call(int i, int a, int b)
{
return functions[i](a, b);
}
The only problem that I can see in the solution from above is that there is no check for the array index (you may get some tricky problems).
To make the code more robust, you can add a check for the index (boundaries), like
add one if statement inside of function "call" where you check the parameter i (not to be bigger than the maximum value)

Returning a pointer to a function in C syntax

In one of the answer to How do function pointers in C work? one user explains how to use function pointers in return values. Here's the code in question:
// this is a function called functionFactory which receives parameter n
// and returns a pointer to another function which receives two ints
// and it returns another int
int (*functionFactory(int n))(int, int) {
printf("Got parameter %d", n);
int (*functionPtr)(int,int) = &addInt;
return functionPtr;
}
For me the way you declare the functionFactory function is very weird - it seems to me that you mix up the return type (pointer to a function) and the function name itself (functionFactory).
For example, when we write a simple function that returns a square of its argument we write something like
int square(int n){
return n*n;
}
Clearly, the type of what we return is on the left and then we write the function name and then what parameters it accepts. So when we return a pointer to a function why don't we write something like:
( int (*function)(int, int) ) functionFactory(int n) { ...
Here the return type (which is a pointer to a function) and its details (e.g. what the function that we point to returns and what it accepts as parameters) is clearly on the left separated and the name of the functionFactory function itself is to the right. To me my version seems much more logical and clear, why don't we write it like that?
This falls out of how declarator syntax works. It may help to think in terms of substitution. Here's one way to look it:
T f (); // f is a function returning T
|
v
T (*p) (); // p is a pointer to a function returning T
|
v
T (*q())(); // q is a function returning a pointer to a function returning T
So we start with the function declarator f(). Then we replace f with the pointer (*p), giving us the declarator (*p)(). Finally we replace p with the function q(), giving us the declarator (*q())().
Edit
You may hear people talk about the "spiral rule" when reading hairy declarators. While it's more of a guideline than an actual rule, it falls out of the following precedence rules:
T *a[N]; // a is an array of pointer to T
T (*a)[N]; // a is a pointer to an array of T
T *f(); // f is a function returning T
T (*f)(); // f is a pointer to a function returning T
The postfix [] and () operators have higher precedence than unary *, hence the need for parentheses when declaring pointers to arrays or functions. So when we read T (*q())();, we start from the leftmost identifier q and "spiral" outwards:
+-----------+
| +-------+ |
| | +---+ | |
| | | | | |
T ( * q ()) ()
| | | | | |
| | +-+ | |
| +-----+ |
+---------+
Breaking it down piece by piece:
q -- q is a
q() -- function returning
*q() -- pointer to
(*q())() -- function returning
T (*q())(); -- T
You cannot declare arrays of function type, nor can you declare functions to return array types:
T a[N](); // NOT ALLOWED
T f()[N]; // NOT ALLOWED
so in any combination of function and array types, a pointer will always be involved, so the spiral rule holds.
The following code declares a variable named func to be a pointer to a function that returns an int and takes two ints as parameters:
int (*func)(int, int);
This syntax mimics the syntax how functions are declared in C:
int func(int, int);
See how similar that is? In fact functions in C are just like variables pointing to functions, e.g. see this sample:
int funcA(int a, int b) { ... }
int (*funcB)(int, int) = funcA;
It plays no role through the rest of the code if you call funcA(a,b) or funcB(a,b), does it? So even though funcB is a variable and funcA a function, the truth is, there's a function somewhere in memory and funcA and funcB are both pointers to the address of the function code.
If you want to nitpick, funcA is a constant and funcB is a variable, so the compiler output for a call to funcA will be different than for funcB; also in one case it is a direct call and in one case an indirect call, as the destination of funcB can change over time. This is also what the asterisk is saying, "I'm not a function, I'm a pointer to a function".
It's important to note that in C the asterisk is always next to the variable name to mark that a pointer variable, so how else would you like to write it instead? Like this?
// Careful! Wrong!
int (int, int) *func;
Does that look more readable to you? Or maybe like that?
// Careful! Wrong!
int ()(int, int) *func;
This syntax is not very clear either and it doesn't mimic any other existing C syntax. If you work a lot with function pointers, pass them around and store them in variables, you should declare an own type for your function pointer:
#include <stdio.h>
int sum ( int a, int b ) {
return (a + b);
}
typedef int (* MathFuncType)(int, int);
MathFuncType getSumFunc ( ) {
return ∑
}
int main(void) {
MathFuncType func = getSumFunc();
printf("%d\n", func(3, 8));
return 0;
}
http://rextester.com/GEKR20461

Using C functions in Swift that take functions as arguments

I'm writing a wrapper around a C mathematical library. Every function takes one or two functions as arguments. However, the arguments for those child functions (as well as the parent functions) are not Swifty -hence the wrapper.
I've cleaned up the example code to just show the three main pieces: the c-library function, the desired Swift function that would be passed to the wrapper (body not shown, but wrapping around the c-library function), and the required C function form.
//C library function, that calls the passed function dozens, hundreds or thousands of times, each time it changes the data provided in p, and uses the output from x
//The Swift arrays are passed as pointers, and the length of the and x array are m and n respectively
returnValue = cLibraryFunc(passedFunc, &p, &x, Int32(m), Int32(n), Int32(itmax), &opts, &info, &work, &covar, &adata)
//I would like to create a Swift function that would look like this (internals could be any myriad of things that takes inputs p and adata and returns data in x:
func desiredSwifty(p: inout [Double], x: inout [Double], m: Int, n: Int, adata: inout [Double]) {
//very simple example
//this example knows the length of p (so m as well)
//and assumes that adata length is the same as the x length (n)
//obviously, it could ifer m and n from p.count and x.count
for i in 0..<n {
x[i] = p[0] + p[1]*adata[i] + p[2]*pow(adata[i], 2)
}
}
//And the wrapper would "convert" it -internally- into the form that the C library function requires:
func requiredC(p: UnsafeMutablePointer<Double>?, x: UnsafeMutablePointer<Double>?, m: Int32, n: Int32, adata: UnsafeMutablePointer<Void>?) {
//same thing, but using pointers, and uglier
//first, have to bitcast the void back to a double
let adataDouble : UnsafeMutablePointer<Double> = unsafeBitCast(adata, to: UnsafeMutablePointer<Double>.self)
for i in 0..<Int(n) {
x![i] = p![0] + p![1]*adataDouble[i] + p![2]*pow(adataDouble[i], 2)
}
}
addition
I should add that I have access to the c source code, so I could possibly add some dummy parameters (possibly to find a way to pass context in). But given that the docs seem to indicate that one can't grab context with a c function pointer, this may be of no use.
(Note: the following example uses Swift 3 on Xcode 8 beta 2.)
Your question is about C functions taking another C function as an argument, so let us reduce the question to that problem. Here is a simple C function which takes a single argument which is
again a C function which takes a pointer to an array of doubles
and an integer count:
// cfunction.h:
void cFunc(void (*func)(double *values, int count));
// cfunction.c:
void cFunc(void (*func)(double *values, int count)) {
double x[] = { 1.2, 3.4, 5,6 };
func(x, 3);
}
This function is imported to Swift as
func cFunc(_ func: (#convention(c) (UnsafeMutablePointer<Double>?, Int32) -> Swift.Void)!)
Here #convention(c) declares the block to have C-style calling
conventions. In particular, from Swift you can pass only a global function or a closure which does not capture any context.
A simple example for a Swift wrapper is
func swiftyFunc(passedFunc: (#convention(c) (UnsafeMutablePointer<Double>?, Int32) -> Void)) {
cFunc(passedFunc)
}
which you can use like this:
func functionToPass(values: UnsafeMutablePointer<Double>?, count: Int32) {
let bufPtr = UnsafeBufferPointer(start: values, count: Int(count))
for elem in bufPtr { print(elem) }
}
swiftyFunc(passedFunc: functionToPass)
or with a closure argument:
swiftyFunc { (values, count) in
let bufPtr = UnsafeBufferPointer(start: values, count: Int(count))
for elem in bufPtr { print(elem) }
}
Do you know that you can get a mutable pointer to a var just by using the & operator? It does the "right thing" on arrays too.
func foo(_ x: UnsafeMutablePointer<Int>) {
print(x)
}
func bar(_ x: UnsafeMutablePointer<Int>) {
print(x)
}
var array = [0]
foo(&array)
var int = 0
bar(&int)
(Tested on Swift 2, but most likely still valid on Swift 3.)
I suspect that this could drastically reduce your need for wrappers.

C array of function pointers

I have the following piece of code that I don't fully understand :
void (*foo[ABC]) (int *i) {
[A] = function1,
[B] = function2,
[C] = function3
}
Where A, B and C are integer constants.
1- Is it a valid declaration if ABC has not been defined before?
2- What is this way of initializing called? ([A] = function1;)
3- What is the value of foo[D]? Is it a null pointer?
No, it won't work if either ABC or A, B or C are not defined.
The initializers are so called designated initializers (for C90 a GNU extension and standard since C99, thanks AndreyT)
As long as D < ABC, foo[D] will be 0 (equivalent to a NULL-pointer), otherwise it will be undefined.
EDIT: as the question is now about what it would mean if ABCRandom and the other indexers are strings the answer is a lot shorter: it won't mean anything, using strings as array indexes is undefined behaviour.
"I don't think it's C" is not equivalent with "it is not C".
Thanks for the link, #Kninnug -- this is a horrible C99 feature (and a GNU extension to C90), and the code has an error: it is a misspelled initialization of an array of three function pointers. I could imagine the fixed code like this:
#define ABC 3
#define A 0
#define B 1
#define C 2
void function1(int *i)
{
}
void function2(int *i)
{
}
void function3(int *i)
{
}
int main(int argc, char *argv[])
{
void (*foo[ABC]) (int *i) = {
[A] = function1,
[B] = function2,
[C] = function3
};
return 0;
}
This compiles.
Also:
What is the value of foo[D]? Is it a null pointer?
Well, what's D? If D >= ABC (assuming that they both are non-negative integers), then that element doesn't even exist. If D < ABC, then it is a NULL pointer, since aggregate (structure, union and array) initialization implicitly zero-initializes elements that have no corresponding initializer expression in the initializer list.
(More precisely, they are initialized "as if they had static storage duration", which is initialization to NULL in the case of pointers.)

Resources