I have a piece of .NET code which I want to port to 64-bit. The codes basically is a set of P/Invoke calls to some other C dll. One of the functions in the C dll has a parameter 'size_t'. What datatype should I use in my P/Invoke signature so that the marshalling works fine. I was thinking of using a IntPtr or a UIntPtr but some say that they are a pointer equivalent thing in .NET and shouldnt be using it. Does anyone know what the correct type for this is?
I've found a dirty hack that can help you achieve similar behavior. It requires that you define a compilation symbol _WIN64
for your 64-bit builds and then you can do the following:
#if _WIN64
using size_t = UInt64;
#else
using size_t = UInt32;
#endif
Note: you will have to use the above code in every file that wants to utilize the size_t
type.
You can also define your own integer type (much like UInt64 is defined) and reuse it without having to put the above code in every file that needs access to size_t
, but it's very complicated (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
}
This will allow size_t
to change it's type depending on the platform, but correctly overloading the necessary operators is very tricky!
size_t
unless you're working with a C++ dll, so in that case you wouldn't compile with Any CPU and it should work. It's a dirty enough hack that there are very few cases that warrant using it. –
Bacchanal As of C# v9 (which requires dotnet 5 or newer) we now have "native sized" integer types in the form of nint
and nuint
, which have the same basic behaviour as IntPtr
and UIntPtr
respectively. This makes nuint
an ideal type to use when a p/invoke target requires a size_t
, without the need for the extra marshalling magic linked to in Patrick McDonald's answer.
If size_t varies depending on the platform, you'll have to use IntPtr. If it is a fixed size integer, use int, uint or long (depending on the original declaration).
© 2022 - 2024 — McMap. All rights reserved.