9
votes

C # Commande pour obtenir la structure offset?

Supposons que j'ai une structure C # comme ceci:

if (n >= offsetof(IMAGE_DOS_HEADER.e_lfanew) + sizeof(int)) {
    ...
}

c#

1 commentaires

Wow, je ne pensais pas que j'aurais une vraie réponse (à l'exception de Nobugz), et ici j'ai trois choix! Je savais à peine qui choisir, alors je les ai tous levés tous. Il suffit de définir simplement des constantes est une approche raisonnable, mais il est en quelque sorte ennuyeux de la manière dont il obscurcisse la mise en page de la structure. J'apprends toujours les subtilités de gérées / non gérées, mais je pense que WJ32 a raison que puisque le compilateur me laissait déjà obtenir un pointeur sur la structure, je sais que les accouchements gérés / non gérées sont les mêmes. Je vais donc avec sa réponse car il semble produire le code le plus facile à lire. Merci à tous pour de si bonnes réponses!


3 Réponses :


7
votes

Oui, vous pouvez le faire à l'aide de la réflexion.

Console.WriteLine(FieldOffset<IMAGE_DOS_HEADER>("e_lfanew"));


6 commentaires

+1 convenu. La réflexion est la voie la plus sûre (déterministe et maintenable) d'aborder cette question.


Dans le contexte d'éviter la répétition de code, la définition d'une constante (comme suggérée par Nobugz) est presque toujours un choix bien meilleur que d'utiliser la réflexion. Il existe des cas où la réflexion est appropriée mais évitant la répétition de code peut généralement être faite d'une autre manière. Cela dit, la réflexion pourrait être plus simple car il y a beaucoup de ces chiffres. NOTE: Je ne suis pas le bownvoter.


@Brian: Ce n'est pas clair s'il a accès à la définition de la structure ou non. S'il le fait, je suis d'accord. S'il ne le fait pas, une autre approche est nécessaire.


@Jason: Et maintenant, après avoir vu la réponse de WJ32, votre réponse me frappe comme une voie surchargée dans ce cas.


@Brian: Voir mon commentaire à la réponse de WJ32.


@Jason: Et vois ma réponse à votre commentaire.



6
votes

Eh bien, vous avez déjà utilisé un nombre magique dans la déclaration de structure. Pourrait aussi bien faire cela: xxx


2 commentaires

Et s'il n'a pas accès à la définition de la structure? Je suis d'accord que ce n'est pas clair s'il le fait ou ne le fait pas.


@Jason: S'il ne fonctionnera pas, cela ne fonctionnera pas. Mais je ne vois pas beaucoup de besoin de signaler cela comme une faille dans cette méthode, car elle est évidente.



20
votes

Utilisez marshal.offsetof: xxx


5 commentaires

+1. Wow, c'est exactement ce qu'il a demandé (bien que je me sente toujours plus à l'aise avec la réponse de Nobugz, en supposant que c'est pratique).


Je ne sais pas à ce sujet; Le maréchal est destiné à être géré et non géré. Ainsi, à partir de la documentation " offsetof fournit le décalage en termes de mise en page de la structure non géré, qui ne correspond pas nécessairement au décalage de la disposition de la structure gérée ." Donc, dans certains cas, cela pourrait donner la mauvaise réponse.


Et pourquoi voudriez-vous connaître la structure gérée offset? Même si vous saviez que vous ne seriez pas en mesure de l'utiliser de quelque manière que ce soit, car même l'obtention d'un pointeur à la structure signifie qu'il est fiable. Votre observation est complètement non pertinente à des fins pratiques.


Cela fonctionne pour le cas spécifique de la question. Cela ne fonctionnera pas en général. Par exemple, si vous avez une structure avec un ou plusieurs champs typés de bool, Tailleof (BOOL) == 1, mais marshal.sizeof (type (BOOL)) = 4. Les compensations seront également incorrectes de Marshal.Offsetof. En d'autres termes, la fonction Marshal.Offsetof donne le décalage inintégré de la structure Marshaled , qui peut être différente des compensations non mises à l'eau.


Peut être utilisé pour les champs / accessoires dans les structures de structures? Comment cela doit être nommé? Disons pour: Struct1.struct2.Prop1 Quel est l'identifiant de PROP1 dans StrCT1?