2017-06-21 2 views
1

Je travaille avec une API C qui définit une structure avec const char * et une fonction qui retourne un char * et qui essaie de trouver la meilleure façon d'effectuer l'affectation.Affectation de la valeur UnsafeMutablePointer à UnsafePointer sans safeBitCast

Existe-t-il un moyen de le faire sans utiliser safeBast? Si je ne mets pas le casting je reçois cette erreur:

Cannot assign value of type 'UnsafeMutablePointer<pchar>' 
(aka 'UnsafeMutablePointer<UInt8>') 
to type 'UnsafePointer<pchar>!' 
(aka 'ImplicitlyUnwrappedOptional<UnsafePointer<UInt8>>') 

Aussi, sera l'initialisation de pairPtr ci-dessous à l'aide paire() allouer une struct paire sur la pile pour initialiser la paire allouée sur le tas parce que cela semble inefficace dans le cas où la structure doit juste être mise à zéro.

est un exemple de code ici:

tête de la bibliothèque C (réduite au minimum pour démontrer le problème):

#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__ 

Mon code Swift:

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) 

Le code C:

#include "pair.h" 
#include <string.h> 

pchar* 
pstrdup(const pchar* str) { 
    return strdup(str); 
} 

Le module définition e:

module pair [extern_c] { 
    header "pair.h" 
    export * 
} 
+0

Pourquoi ne pas simplement 'let p = pair (left: leftVal, right: rightVal)'? Je ne vois pas pourquoi le safeBit devrait être nécessaire, peut-être que je néglige quelque chose? –

+0

Cela fonctionnerait mais pour la structure réelle il y a 20 attributs et j'attribue seulement des valeurs à environ 5. Y at-il un moyen simple d'assigner directement sans la distribution? – Julian

+0

Si le seul problème est la mutabilité différente, alors 'p.left = UnsafePointer (leftVal)' devrait fonctionner. –

Répondre

1

Vous pouvez créer un UnsafePointer<T> d'un UnsafeMutablePtr<T> simplement avec

let ptr = UnsafePointer(mptr) 

utilisant le

/// 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>) 

initialiseur de UnsafePointer. Dans votre cas ce serait par exemple

p.left = UnsafePointer(leftVal)