DotNetSpartan
DotNetSpartan

Reputation: 1001

Convert int to UIntPtr in C#

Thanks in advance.

In the following piece of simple code, the model.Count is an System.Int32 integer which I get from the a third party library named Xilium.CefGlue (v107). I iterate over this integer to get the value based on the index.

 indexCollection = cefMenuModel.Count;
 for(int x=0;x<indexCollection;x++)
 {
   var value = GetCommandIdAt(x); 
 }

In the latest version of CefGlue library, The cefMenuModel.Count value has been changed from System.Int32 integer to UIntPtr and since then I am finding type conversion and '<' operator cannot be applied on UIntPtr compile time error messages.

The GetCommandIdAt(x) in the older version of C++ library took parameter as an integer but now in the latest version it is expecting the parameter as UIntPtr.

What change can I make in my above piece code to change the int type to UIntPtr. Basically I want to iterate over a collection of UIntPtr that I receive from cefMenuModel.Count and pass that UIntPtr value to GetCommandIdAt(x) ?

The Xelium.CefGlue expects the GetCommandIdAt as:

 namespace Xilium.CefGlue
{
    
    [NullableAttribute(0)]
    [NullableContextAttribute(1)]
    public sealed class CefMenuModel : IDisposable
    {
        ~CefMenuModel();

        //
        // Summary:
        // Returns the number of items in this menu.
        [NativeIntegerAttribute]
        public UIntPtr Count { get; }
       
        // Summary:
        // Returns the command id at the specified |index| or -1 if not found due to invalid
        // range or the index being a separator.
        public int GetCommandIdAt([NativeIntegerAttribute] UIntPtr index);
    
     }
}

Upvotes: 1

Views: 727

Answers (1)

Matthew Watson
Matthew Watson

Reputation: 109597

Assuming that the UIntPtr values will be in the range of a 32-bit integer (which I assume they must be, because you can't address more than 2^31 items in an array in C#), then you can just freely cast between a UIntPtr and an int:

UIntPtr uip1 = new UIntPtr(34234);

Console.WriteLine(uip1); // 34234
        
int i = (int) uip1;  // Cast from UIntPtr to int

Console.WriteLine(i); // 34234

UIntPtr uip2 = (UIntPtr) i;

Console.WriteLine(uip2); // 34234

Also note that you can now use the nuint type instead of UIntPtr and the nint type instead of IntPtr:

nuint uip1 = 34234;

Console.WriteLine(uip1); // 34234
        
int i = (int) uip1;  // Cast from nuint to int

Console.WriteLine(i); // 34234

nuint uip2 = (nuint) i;

Console.WriteLine(uip2); // 34234

IMPORTANT:

It's totally weird that the authors of the library would make this change. The size of a UIntPtr (and nuint) is 64 bits when running as x64 and 32 bits when running as x86. This means that casting to int will fail on an x64 build if the value exceeds 2^31.

As I said earlier, a value of greater than 2^31 is NOT supported for array or list indexing in C#, so if it exceeds that value you're stuffed either way.

Upvotes: 1

Related Questions