I am working with a C API that defines a structure with const char* and a function that returns a char* and am trying to find the best way to do the assignment.
Is there a way to do this without using unsafeBitCast? If I don't put the cast then I get this error:
Cannot assign value of type 'UnsafeMutablePointer<pchar>'
(aka 'UnsafeMutablePointer<UInt8>')
to type 'UnsafePointer<pchar>!'
(aka 'ImplicitlyUnwrappedOptional<UnsafePointer<UInt8>>')
Also, will the initialization of pairPtr below using pair() allocate a pair struct on the stack to initialize the allocated pair on the heap because this seems inefficient for the case where the structure just has to be zero'd out.
Here is sample code:
C library header (minimized to demonstrate the problem):
#ifndef __PAIR_INCLUDE__
#define __PAIR_INCLUDE__
typedef unsigned char pchar;
pchar*
pstrdup(const pchar* str);
typedef struct _pair {
const pchar* left;
const pchar* right;
} pair;
#endif // __PAIR_INCLUDE__
My Swift code:
import pair
let leftVal = pstrdup("left")
let rightVal = pstrdup("right")
let pairPtr = UnsafeMutablePointer<pair>.allocate(capacity: 1)
pairPtr.initialize(to: pair())
// Seems like there should be a better way to handle this:
pairPtr.pointee.left = unsafeBitCast(leftVal, to: UnsafePointer<pchar>.self)
pairPtr.pointee.right = unsafeBitCast(rightVal, to: UnsafePointer<pchar>.self)
The C code:
#include "pair.h"
#include <string.h>
pchar*
pstrdup(const pchar* str) {
return strdup(str);
}
The module definition:
module pair [extern_c] {
header "pair.h"
export *
}
You can create an UnsafePointer<T>
from an UnsafeMutablePtr<T>
simply with
let ptr = UnsafePointer(mptr)
using the
/// Creates an immutable typed pointer referencing the same memory as the
/// given mutable pointer.
///
/// - Parameter other: The pointer to convert.
public init(_ other: UnsafeMutablePointer<Pointee>)
initializer of UnsafePointer
. In your case that would for example be
p.left = UnsafePointer(leftVal)