2009-04-21 4 views
10

Mam fragment kodu .NET, który chcę przenieść do wersji 64-bitowej. Kody są w zasadzie zbiorem wywołań P/Invoke do innych bibliotek dll C. Jedna z funkcji w bibliotece dll C ma parametr "size_t". Jaki typ danych powinienem używać w moim sygnaturze P/Invoke, aby układanie działało poprawnie. Myślałem o używaniu IntPtr lub UIntPtr, ale niektórzy twierdzą, że są one rzeczą równoważną wskaźnikowi w .NET i nie powinni go używać. Czy ktoś wie, jaki jest właściwy typ?. Odpowiednik .NET size_t

+0

Co to jest "bit-ness"? –

Odpowiedz

17

UIntPtr zadziała (IntPtr prawdopodobnie działa zbyt, ale size_t jest niepodpisany, więc UIntPtr jest lepsze dopasowanie)

JaredPar napisał coś na jego blog (a follow-up) na ten temat.

1

Jeśli size_t różni się w zależności od platformy, będziesz musiał użyć IntPtr. Jeśli jest to stała liczba całkowita, użyj int, uint lub long (w zależności od oryginalnej deklaracji).

1

przyjrzeć się tej Document by Microsoft

mówi dla 64 bitowych aplikacji size_t jest 64 bit int.

Jednakże, jeśli DLL dzwonisz jest dll 32 bit, tylko trzeba przejść int 32bit

1

Znalazłem brudną hack, który może pomóc w osiągnięciu podobnego zachowania. To wymaga zdefiniowania symbolu kompilacji _WIN64 na 64-bitowym buduje, a następnie można wykonać następujące czynności:

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

Uwaga: trzeba będzie użyć powyższego kodu w każdym pliku, który chce wykorzystać typ size_t .

Można również zdefiniować własny typ liczby całkowitej (podobnie jak zdefiniowano UInt64) i użyć go ponownie bez konieczności umieszczania powyższego kodu w każdym pliku wymagającym dostępu do size_t, ale jest to bardzo skomplikowane (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 
} 

Pozwoli to size_t zmienić to typ w zależności od platformy, ale poprawnie przeciążenia niezbędne operatorów jest bardzo trudne!

+1

Konieczność zdefiniowania symbolu kompilacji oznacza, że ​​nie będzie działać dla żadnych kompilacji CPU, i zawiesi się, jeśli ktoś zmodyfikuje plik wykonywalny, aby działał jak coś innego (x86/x64). –

+0

@ ØysteinE.Krog Zgadzam się, również ogólnie uważam, że tak naprawdę nie potrzebujesz 'size_t', chyba że pracujesz z biblioteką C++, więc w takim przypadku nie skompilowałbyś się z Dowolnym CPU i to powinno działać. To wystarczająco brudny hack, że jest bardzo mało przypadków, które uzasadniają jego użycie. – Kiril