Voici une structure en Swift :
struct A {
var x
var y
var z
}
Que dois-je faire pour obtenir le décalage de y
dans la structure A
tout comme offsetof(A, y)
en C ?
Merci :)
Voici une structure en Swift :
struct A {
var x
var y
var z
}
Que dois-je faire pour obtenir le décalage de y
dans la structure A
tout comme offsetof(A, y)
en C ?
Merci :)
Swift ne définit pas actuellement de disposition mémoire standard pour les structures définies en Swift. Cela signifie que tout code que vous écrivez pour décomposer une structure via les mathématiques des pointeurs n'est pas garanti de fonctionner sur les futures versions, ou même sur les mises à jour mineures du compilateur Swift. (Comme le note @robmayoff, cela fait partie de l'obtention par Swift d'une ABI stable, l'un des objectifs du projet Swift pour la version 5 cette année).
Cependant, si votre structure est définie en C et importée via un en-tête de transition, Swift respecte la disposition binaire de sa mémoire en C. Dans ce cas, l'en-tête MemoryLayout
fournit des équivalents au type C sizeof
opérateur et autres utilitaires similaires. Il n'y a toujours pas offsetof
mais vous pouvez faire le calcul du pointeur vous-même en ajoutant l'élément stride
des types de membres dans l'ordre de déclaration C.
Par exemple, les documents d'Apple pour SCNGeometrySource
avoir un exemple de création d'un objet 3D à partir d'un tampon de données entrelacées de coordonnées de vertex/normales/textures. Mais il est (actuellement) écrit en ObjC, avec l'utilisation de sizeof
y strideof
pour indiquer à SceneKit où trouver chaque type de données dans le tampon. L'équivalent en Swift utiliserait MemoryLayout<Float>.size
à la place de sizeof(float)
etc., et au lieu de offsetof(MyVertex, nx)
vous devez observer qu'il y a trois flottants dans la structure avant la balise nx
et écrire MemoryLayout<Float>.stride * 3
.
Vous ne pouvez pas obtenir le décalage de y
de manière fiable, car Swift ne prend pas encore en charge cette opération. Elle sera éventuellement prise en charge après la mise en œuvre de la " stabilité ABI ".
L'approche actuellement recommandée consiste à définir le struct
en C, et définissent également des fonctions C pour retourner les décalages des champs.
MemoryLayout.offset(of:)
a été ajouté dans Swift 4.2, avec l'implémentation de la fonction
Exemple :
struct A {
var x: Int8
var y: Int16
var z: Int64
}
MemoryLayout.offset(of: \A.x) // 0
MemoryLayout.offset(of: \A.y) // 2
MemoryLayout.offset(of: \A.z) // 8
Remarques : Cela devrait fonctionner également, mais (à partir de Swift 4.2) ne compile pas (bug SR-8335 ) :
MemoryLayout<A>.offset(of: \.y)
// error: Expression type 'Int?' is ambiguous without more context
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.