Using C functions in Swift that take functions as arguments -


i'm writing wrapper around c mathematical library. every function takes 1 or 2 functions arguments. however, arguments child functions (as parent functions) not swifty -hence wrapper.

i've cleaned example code show 3 main pieces: c-library function, desired swift function passed wrapper (body not shown, wrapping around c-library function), , required c function form.

//c library function, calls passed function dozens, hundreds or thousands of times, each time changes data provided in p, , uses output x //the swift arrays passed pointers, , length of , x array m , n respectively returnvalue = clibraryfunc(passedfunc, &p, &x, int32(m), int32(n), int32(itmax), &opts, &info, &work, &covar, &adata)   //i create swift function (internals myriad of things takes inputs p , adata , 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 length of p (so m well)     //and assumes adata length same x length (n)     //obviously, ifer m , n p.count , x.count      in 0..<n {         x[i] = p[0] + p[1]*adata[i]  + p[2]*pow(adata[i], 2)     } }   //and wrapper "convert" -internally- form c library function requires: func requiredc(p: unsafemutablepointer<double>?, x: unsafemutablepointer<double>?, m: int32, n: int32, adata: unsafemutablepointer<void>?) {     //same thing, using pointers, , uglier      //first, have bitcast void double     let adatadouble : unsafemutablepointer<double> = unsafebitcast(adata, to: unsafemutablepointer<double>.self)      in 0..<int(n) {         x![i] = p![0] + p![1]*adatadouble[i]  + p![2]*pow(adatadouble[i], 2)     } } 

addition

i should add have access c source code, possibly add dummy parameters (possibly find way pass context in). given docs seem indicate 1 can't grab context c function pointer, may of no use.

(note: following example uses swift 3 on xcode 8 beta 2.)

your question c functions taking c function argument, let reduce question problem. here simple c function takes single argument again c function takes pointer array of doubles , 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 imported swift as

func cfunc(_ func: (@convention(c) (unsafemutablepointer<double>?, int32) -> swift.void)!) 

here @convention(c) declares block have c-style calling conventions. in particular, swift can pass global function or closure not capture context.

a simple example swift wrapper is

func swiftyfunc(passedfunc: (@convention(c) (unsafemutablepointer<double>?, int32) -> void)) {     cfunc(passedfunc)  } 

which can use this:

func functiontopass(values: unsafemutablepointer<double>?, count: int32) {     let bufptr = unsafebufferpointer(start: values, count: int(count))     elem in bufptr { print(elem) } }  swiftyfunc(passedfunc: functiontopass) 

or closure argument:

swiftyfunc { (values, count) in     let bufptr = unsafebufferpointer(start: values, count: int(count))     elem in bufptr { print(elem) } } 

Comments

Popular posts from this blog

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12:test (default-test) on project.Error occurred in starting fork -

windows - Debug iNetMgr.exe unhandle exception System.Management.Automation.CmdletInvocationException -

configurationsection - activeMq-5.13.3 setup configurations for wildfly 10.0.0 -