2009-04-21 5 views
10

J'ai un morceau de code .NET que je veux porter en 64 bits. Les codes sont essentiellement un ensemble d'appels P/Invoke à un autre dll C. L'une des fonctions de C dll a un paramètre 'size_t'. Quel type de données dois-je utiliser dans ma signature P/Invoke pour que le triage fonctionne correctement. Je pensais à utiliser un IntPtr ou un UIntPtr mais certains disent qu'ils sont un pointeur équivalent en .NET et ne devraient pas l'utiliser. Est-ce que quelqu'un sait quel est le bon type pour cela?. NET équivalent de size_t

+0

Quel "bit-ness" est la DLL C? –

Répondre

17

UIntPtr fonctionnera (IntPtr marcherait probablement aussi, mais size_t est non signé, donc UIntPtr est un meilleur ajustement)

JaredPar a écrit quelque chose sur son blog (et follow-up) à ce sujet.

1

Si size_t varie en fonction de la plate-forme, vous devrez utiliser IntPtr. S'il s'agit d'un entier de taille fixe, utilisez int, uint ou long (selon la déclaration d'origine).

1

un coup d'oeil à ce Document by Microsoft

Il dit pour size_t d'application 64 bits est de 64 bits int.

Cependant, si la DLL que vous appelez est une dll 32 bits, il vous suffit de passer un 32bit int

1

J'ai trouvé un sale hack qui peut vous aider à atteindre un comportement similaire. Il exige que vous définissez un symbole de compilation _WIN64 pour votre 64 bits construit et vous pouvez faire ce qui suit:

#if _WIN64 
    using size_t = UInt64; 
#else 
    using size_t = UInt32; 
#endif 

Note: vous devrez utiliser le code ci-dessus dans chaque fichier qui veut utiliser le type size_t .

Vous pouvez également définir votre propre type entier (comme UInt64 est défini) et le réutiliser sans avoir à mettre le code ci-dessus dans tous les fichiers ayant besoin d'accéder à size_t, mais c'est très compliqué (imho).

#if _WIN64 
    using _size_t = UInt64; 
#else 
    using _size_t = UInt32; 
#endif 

[Serializable] 
[CLSCompliant(false)] 
[ComVisible(true)] 
public struct size_t : IComparable, IFormattable, IConvertible, IComparable<_size_t>, IEquatable<_size_t> 
{ 
    private _size_t _value; 

    public size_t(_size_t val) 
    { 
     _value = val; 
    } 

    // You have to add all of your overloads below 
} 

Cela permettra size_t de changer son type en fonction de la plate-forme, mais la surcharge correctement les opérateurs nécessaires est très délicat!

+1

Avoir à définir le symbole de compilation signifie que cela ne fonctionnera pas pour toutes les générations de CPU, et il se bloquera si quelqu'un modifie l'exécutable pour l'exécuter comme autre chose (x86/x64). –

+0

@ ØysteinE.Krog Je suis d'accord, je trouve aussi que vous n'avez pas vraiment besoin de 'size_t' à moins que vous ne travailliez avec une DLL C++, donc dans ce cas vous ne compilez pas avec Any CPU et ça devrait marcher. C'est un hack assez sale qu'il y a très peu de cas qui justifient l'utilisation. – Kiril

Questions connexes