Manual Pages for UNIX Darwin command on man ffi_prep_closure
MyWebUniversity

Manual Pages for UNIX Darwin command on man ffi_prep_closure

ffiprepclosure(3) BSD Library Functions Manual ffiprepclosure(3)

NAME

ffffiipprreeppcclloossuurree - Prepare a ffffiicclloossuurree for execution.

SYNOPSIS

##iinncclluuddee <>

ffistatus ffffiipprreeppcclloossuurree(fficlosure *closure, fficif *cif, void (*fun)(fficif*,void*,void**,void*), void *userdata);

DESCRIPTION

closure is prepared to execute fun. cif contains information describing the data types, sizes and alignments of the arguments to and return value from the function that will be called from fun, and must be initialized with ffffiipprreeppcciiff before it is used with ffffiipprreeppcclloossuurree. userdata may point to additional data to be used in fun. If no additional data is needed, userdata may be NNUULLLL. When closure is invoked, fun is called with cif, an array of pointers to arguments, a pointer to a return value, and userdata. Some architectures do not allow the execution of data by default. In such cases, it is necessary to manually alter the permissions of the page that contains closure prior to its execution.

RETURN VALUES

Upon successful completion, ffffiipprreeppcclloossuurree returns FFFFIIOOKK. If the ABI specified in cif does not refer to a valid ABI, FFFFIIBBAADDAABBII will be

returned. Available ABIs are defined in <> and

<>.

EEXXAAMMPPLLEESS

#define MACOSX // for fficonfig.h on Darwin

#include

#include // for mmap()

unsigned char foo(unsigned int, float); static void fooclosure(fficif*, void*, void**, void*); int main(int argc, const char **argv) { fficif cif; fficlosure *closure; ffitype *argtypes[2]; ffiarg result; ffistatus status; // Specify the data type of each argument. Available types are defined // in . argtypes[0] = &ffitypeuint; argtypes[1] = &ffitypefloat; // Allocate a page to hold the closure with read and write permissions. if ((closure = mmap(NULL, sizeof(fficlosure), PROTREAD | PROTWRITE,

MAPANON | MAPPRIVATE, -1, 0)) == (void*)-1)

{ // Check errno and handle the error. } // Prepare the fficif structure. if ((status = ffiprepcif(&cif, FFIDEFAULTABI, 2, &ffitypeuint8, argtypes)) != FFIOK) { // Handle the ffistatus error. } // Prepare the fficlosure structure. if ((status = ffiprepclosure(closure, &cif, fooclosure, NULL)) != FFIOK) { // Handle the ffistatus error. } // Ensure that the closure will execute on all architectures.

if (mprotect(closure, sizeof(closure), PROTREAD | PROTEXEC) == -1)

{ // Check errno and handle the error. } // The closure is now ready to be executed, and can be saved for later // execution if desired. // Invoke the closure. result = ((unsigned char(*)(float, unsigned int))closure)(42, 5.1); // Free the memory associated with the closure.

if (munmap(closure, sizeof(closure)) == -1)

{ // Check errno and handle the error. } return 0; } // Invoking the closure transfers control to this function. static void fooclosure(fficif* cif, void* result, void** args, void* userdata) { // Access the arguments to be sent to foo(). float arg1 = *(float*)args[0]; unsigned int arg2 = *(unsigned int*)args[1]; // Call foo() and save its return value. unsigned char retval = foo(arg1, arg2); // Copy the returned value into result. Because the return value of foo() // is smaller than sizeof(long), typecast it to ffiarg. Use ffisarg // instead for signed types. *(ffiarg*)result = (ffiarg)retval; }

// The closed-over function.

unsigned char foo(unsigned int x, float y) {

unsigned char result = x - y;

return result; }

SEE ALSO

ffi(3), ffiprepcif(3), mmap(2), munmap(2), mprotect(2) Darwin July 20, 2007 Darwin




Contact us      |      About us      |      Term of use      |       Copyright © 2000-2019 MyWebUniversity.com ™