I would like to invoke a function that I dynamically loaded with dlopen, and I need to pass data to it. Ideally, I could define a structure, and then pass a pointer to the structure to this function, but I have not found a way to express this in Swift.
In C# I can place the [StructLayout(LayoutKind.Sequential)] on a struct, and then the struct becomes blittable and I can pass a pointer to C functions.
The following declaration shows what I am trying to do:
struct myType {
var a, b, c: Int32
var d: Int8
}
// This is wrong
typealias add_wch_def = @convention(c) (UnsafeMutablePointer<myType>) -> CInt
When I compile that, I get:
'(UnsafeMutablePointer<CursesDriver.myType>) -> CInt' (aka '(UnsafeMutablePointer<CursesDriver.myType>) -> Int32') is not representable in Objective-C, so it cannot be used with '@convention(c)'
Any guidance as to what I could try in this scenario?
Yes; the layout of a tuple is guaranteed to be the basic in-order rounding-to-alignment layout. We don’t guarantee that primitive type alignments will match C in all cases, but if you have a tuple with no need for alignment padding, it should have the obvious layout.
Everything John said is absolutely correct, but: you should still define the structure in a C header that you import, because that way you have a single definition for the layout, rather than two separate definitions that you need to keep in sync if you make changes. One of Swift's big strengths that doesn't get talked about much is its ability to import C API without futzing with memory layout or calling-convention details. Use the C API directly if you can.