Swift: Create Array of Pointers For Calling a C Function

Bryan

Context

From Swift, I am trying to call a specific function of the libxlsxwriter C library. The documentation is here: https://libxlsxwriter.github.io/worksheet_8h.html#a62bf44845ce9dcc505bf228999db5afa

The function assembles a "rich string" (the equivalent of an AttributedString, where different formats/styles apply to different ranges) and writes it to a specific cell in the Excel worksheet. In C, the function works like this:

lxw_format *bold = workbook_add_format(workbook);
format_set_bold(bold);
 
lxw_format *italic = workbook_add_format(workbook);
format_set_italic(italic);
 
lxw_rich_string_tuple fragment11 = {.format = NULL,   .string = "This is "     };
lxw_rich_string_tuple fragment12 = {.format = bold,   .string = "bold"         };
lxw_rich_string_tuple fragment13 = {.format = NULL,   .string = " and this is "};
lxw_rich_string_tuple fragment14 = {.format = italic, .string = "italic"       };
 
lxw_rich_string_tuple *rich_string1[] = {&fragment11, &fragment12,
                                         &fragment13, &fragment14, NULL};
 
worksheet_write_rich_string(worksheet, CELL("A1"), rich_string1, NULL);

The Problem

I have an array of lxw_rich_string_tuple structs, but I'm unclear how to convert this into the array of pointers that worksheet_write_rich_string() accepts:


// The worksheet object and `lxw_format` objects are already existent. 
// This array contains multiple well-formed `lxw_rich_string_tuple` structs, which I can see in the debugger.
//
var rawTuples: [lxw_rich_string_tuple] =  ...


// Parameters: 
//    - the worksheet on which to write this string
//    - the row of the cell in which to write
//    - the column of the cell in which to write
//    - a null-terminated array of pointers to `lxw_rich_string_tuple` structs
//    - an optional format object to use, null in this case.
//
worksheet_write_rich_string(worksheet, 0, 1, ?, NULL);

The trouble is the ?. I've tried all sorts of withUnsafeBytes and withUnsafeMutableBytes and UnsafeMutableRawPointer().bindMemory(to:capacity:) and I cannot figure out the magic Swift gibberish to do what is such a SIMPLE thing in C. Thanks.

My Attempt

This gives no compiler errors, but crashes with a Bad Access exception:

let argsSize: Int = rawTuples.count

rawTuples.withUnsafeMutableBufferPointer { rawTuplesPointer in

    let ptr = UnsafeMutableRawPointer(rawTuplesPointer.baseAddress!).bindMemory(to: lxw_rich_string_tuple.self, capacity: argsSize)
    var tuplePointers: [UnsafeMutablePointer<lxw_rich_string_tuple>?] = []

    for i in 0 ..< argsSize
    {
        let tp: UnsafeMutablePointer<lxw_rich_string_tuple>? = ptr + (i * MemoryLayout<lxw_rich_string_tuple>.stride)           
        tuplePointers.append(tp)
    }
    tuplePointers.append(nil)

    tuplePointers.withUnsafeBufferPointer { tpPointer in

        let m = UnsafeMutablePointer(mutating: tpPointer.baseAddress)
        worksheet_write_rich_string(lxw_worksheet, cell.row, cell.col, m, nil)

    }
}
Sweeper

Try this:

rawTuples.withUnsafeMutableBufferPointer { p in
    guard let arrBaseAddress = p.baseAddress else { return }

    var pointersToEachArrayElement: [UnsafeMutablePointer<_>?] = 
        Array(arrBaseAddress ..< arrBaseAddress.advanced(by: p.count))
    pointersToEachArrayElement.append(nil)
    pointersToEachArrayElement.withUnsafeMutableBufferPointer { q in
        // use q.baseAddress in the call to worksheet_write_rich_string
    }
}

The idea is similar to your attempt - to create an array of pointers to each of the array elements. But unlike your attempt, I avoided calling the initialisers of the pointer types (which I don't think you are supposed to do), and instead tried to use the withXXX functions as much as I could.

You should also consider just writing Objective-C wrappers around the C function and lxw_rich_string_tuple. Sometimes C functions are just not bridged into Swift in a very convenient way, and this is not the first time I've experienced something like this, unfortunately :(

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From

How do I create an array of function pointers of different prototypes?

From Dev

Calling Member Function Pointers

From Dev

Create interface to C function pointers in Rust

From Dev

Calling a C function from Julia and passing a 2D array as a pointer of pointers as argument

From Dev

Representing NULL Function Pointers to C Functions in Swift

From Dev

Create C function pointers structure in Python

From Dev

create array of pointers to files in C programming

From Dev

Array of structures of function pointers C

From Dev

function pointers in array (nix c++)

From Dev

error in array of Function pointers

From Dev

calling recursively a function to create a list in C

From Dev

Calling C function with pointers from F#

From Dev

Calling C function with array pointer and int pointer from Swift

From Dev

C programming: Function using pointers to sort array

From Dev

initialize an array of structs with function pointers in them C

From Dev

How to create an array of pointers to structs? C++

From Dev

C -- Array of Function Pointers

From Dev

C - fwrite dynamic array by a function, pointers

From Dev

How do i create a dynamic array of function pointers?

From Dev

C++ passing array of pointers to function

From Dev

Calling a C library method from swift using pointers

From Dev

Calling C function from Fortran with pointers

From Dev

Decoding declaration(a combination of array and function pointers) in C

From Dev

C : function that calculates the sum of an array using pointers

From Dev

How to create, modify, and return array of pointers in a function in C?

From Dev

Create C Array in Swift and Pass its Pointer to a C Function (in Swift)

From Dev

fill an array of pointers to functions in another function in C

From Dev

Passing an array of pointers to function in C

From Dev

How to explain calling a C function from an array of function pointers?

Related Related

  1. 1

    How do I create an array of function pointers of different prototypes?

  2. 2

    Calling Member Function Pointers

  3. 3

    Create interface to C function pointers in Rust

  4. 4

    Calling a C function from Julia and passing a 2D array as a pointer of pointers as argument

  5. 5

    Representing NULL Function Pointers to C Functions in Swift

  6. 6

    Create C function pointers structure in Python

  7. 7

    create array of pointers to files in C programming

  8. 8

    Array of structures of function pointers C

  9. 9

    function pointers in array (nix c++)

  10. 10

    error in array of Function pointers

  11. 11

    calling recursively a function to create a list in C

  12. 12

    Calling C function with pointers from F#

  13. 13

    Calling C function with array pointer and int pointer from Swift

  14. 14

    C programming: Function using pointers to sort array

  15. 15

    initialize an array of structs with function pointers in them C

  16. 16

    How to create an array of pointers to structs? C++

  17. 17

    C -- Array of Function Pointers

  18. 18

    C - fwrite dynamic array by a function, pointers

  19. 19

    How do i create a dynamic array of function pointers?

  20. 20

    C++ passing array of pointers to function

  21. 21

    Calling a C library method from swift using pointers

  22. 22

    Calling C function from Fortran with pointers

  23. 23

    Decoding declaration(a combination of array and function pointers) in C

  24. 24

    C : function that calculates the sum of an array using pointers

  25. 25

    How to create, modify, and return array of pointers in a function in C?

  26. 26

    Create C Array in Swift and Pass its Pointer to a C Function (in Swift)

  27. 27

    fill an array of pointers to functions in another function in C

  28. 28

    Passing an array of pointers to function in C

  29. 29

    How to explain calling a C function from an array of function pointers?

HotTag

Archive