2009-04-21 24 views
10

Tengo un fragmento de código .NET que quiero transferir a 64 bits. Los códigos básicamente son un conjunto de llamadas P/Invoke a algún otro C dll. Una de las funciones en el dll C tiene un parámetro 'size_t'. ¿Qué tipo de datos debo usar en mi firma de P/Invoke para que la clasificación funcione bien? Estaba pensando en usar un IntPtr o un UIntPtr, pero algunos dicen que son un puntero equivalente en .NET y no deberían usarlo. ¿Alguien sabe cuál es el tipo correcto para esto?.NET equivalente de size_t

+0

¿Qué "bit-ness" es la DLL de C? –

Respuesta

17

UIntPtr funcionará (IntPtr probablemente funcionaría también, pero size_t no tiene signo, por lo UIntPtr es un mejor ajuste)

JaredPar ha escrito algo en su blog (y una follow-up) sobre esto.

1

Si size_t varía según la plataforma, tendrá que usar IntPtr. Si es un entero de tamaño fijo, use int, uint o long (dependiendo de la declaración original).

1

echar un vistazo a este Document by Microsoft

Dice para size_t aplicación de 64 bits es de 64 bits int.

Sin embargo, si el archivo DLL que está llamando es una DLL de 32 bits, sólo tiene que pasar un int de 32 bits

1

he encontrado un truco sucio que puede ayudar a lograr un comportamiento similar. Se requiere que se defina un símbolo compilación _WIN64 para su 64 bits construye y entonces usted puede hacer lo siguiente:

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

Nota: usted tendrá que usar el código anterior en todos los archivos que desea utilizar el tipo size_t .

También puede definir su propio tipo de entero (como UInt64 está definido) y reutilizarlo sin tener que poner el código anterior en cada archivo que necesita acceso a size_t, pero es muy complicado (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 
} 

Esto permitirá size_t para cambiar su tipo dependiendo de la plataforma, pero la sobrecarga correctamente los operadores necesarios es muy difícil!

+1

Tener que definir el símbolo de compilación significa que esto no funcionará para ninguna compilación de CPU, y se bloqueará si alguien modifica el ejecutable para que se ejecute como algo más (x86/x64). –

+0

@ ØysteinE.Krog Estoy de acuerdo, también generalmente descubro que realmente no necesita 'size_t' a menos que esté trabajando con un dll C++, por lo que en ese caso no compilaría con Any CPU y debería funcionar. Es un hack lo suficientemente sucio que hay muy pocos casos que justifiquen su uso. – Kiril