C# StructLayout/FieldOffset et l'indexation dans les tableaux
Je vais avoir un peu d'un problème à l'aide de FieldOffset correctement avec les tableaux. Le code ci-dessous est un exemple de situation où il ne fonctionne pas correctement pour moi:
[StructLayout(LayoutKind.Explicit)]
public struct IndexStruct {
[FieldOffset(0)]
public byte[] data;
[FieldOffset(0)]
public short[] idx16;
[FieldOffset(0)]
public int[] idx32;
}
Si j'ai par exemple définit le tableau nommé "data" pour un sérialisé tableau d'octets, puis essayez de récupérer des données comme des shorts à l'aide de la "idx16" champ de l'indexation est toujours aligné comme un byte[]. Ce qui signifie que idx16Un récupère le deuxième octet de données, pas le second 16bit mot (octets 2 et 3). Si je fais l'inverse je l'indice short au lieu d'octets, ce qui signifie que le décalage de l'alignement est héritée de la source de données. Ma question, est-il un moyen de contourner cela? Je sais que je peux compenser la valeur de l'indice en multipliant la taille de l'élément, mais est-il une autre voie?
Ici est une réponse que j'ai trouvé ici sur StackOverflow, mais lorsque j'essaie ce code, il s'est avéré qu'il ne fonctionnait pas correctement. Il a essayé à l'aide d'une Unité de test de VS avec le code suivant, sans succès:
[TestMethod()]
public void SumTest() {
float[] fArr = {2.0f, 0.5f, 0.0f, 1.0f};
MemoryStream ms = new MemoryStream();
for (int i = 0; i < fArr.Length; i++) {
ms.Write(BitConverter.GetBytes(fArr[i]), 0, sizeof(float));
}
byte[] buff = ms.ToArray();
double expected = 3.5f;
double actual = Sum(buff);
Assert.AreEqual(expected, actual);
}
Merci beaucoup d'avance!
OriginalL'auteur Burre | 2009-05-08
Vous devez vous connecter pour publier un commentaire.
Le problème est (de ce que je peux voir) que vous avez fusionné les références des tableaux - alors quel tableau est la dernière volonté de gagner. Une fois il y a un tableau, c'est l'utilisation de l'indexeur (pas de décalage d'octet) - de sorte que la taille n'a pas d'importance.
La façon de le faire "correctement" (ou mal, selon le cas peut être) serait probablement avec le code unsafe - prendre le pointeur vers le tableau - quelque chose comme:
Bien sûr, je ne suis pas sûr que je vous le conseille, mais qui semble atteindre ce que vous voulez?
Je me demande aussi si vous pouvez déposer le
struct
complètement et de n'utiliser que dangereux l'accès à unbyte[]
directement:Réinterpréter casting réussi références si beaucoup plus problématique que le code unsafe. Il n'y a aucune raison de ne pas le code unsafe si vous ne le faible niveau de stuff, mais en évitant totalement perverti le CLR type de système est MAL. Je suppose que votre réinterpréter fonte conduit à un comportement indéfini et pourraient se briser dans les futures versions de la CLR.
ou, en effet, dans WinRT
OriginalL'auteur Marc Gravell
Votre FieldOffset définit l'emplacement de chacun de vos éléments de données sont à l'intérieur de la structure..
En la mettant tous à 0, vous avez dit au compilateur qu'ils ont tous à la position 0.
La deuxième chose que je vois est que vous êtes en train de créer un tableau d'octets, des shorts et des ints.
voir: MSDN StructLayoutAttribute
OriginalL'auteur datacop