Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conversion of HRESULT between C++ and C#

Tags:

c#

winapi

hresult

I have C++ code which is called from C# using reflection and etc.

The weird thing I encountered is while on C++ side function declaration looks like this

dppFUNC(HRESULT) dppOnlineGetBalanceInfo(

On C# side it is declared as

[DllImport("dppClientModule.dll", CallingConvention = CallingConvention.StdCall)]
private static extern UInt32 dppOnlineGetBalanceInfo(

Why is the return type on C# code uint? Should not it be int?

What problems can it cause? It has been used like this now, and I would like to know what problems could it cause?

The linked question as duplicate seems different because the result of MAKEHRESULT (C# version) there in accepted answer is int, why?


1 Answers

HRESULT is defined as a long (32-bit signed) in C/C++. So technically, in C#, you would use an int. This is also the type Microsoft itself uses in C# for Exception.HResult.

The downside of using int over uint is that you'll have to explicitly cast, while disabling overflow-checking (unchecked), all the constants listed in the MSDN documentation:

For example:

const int E_FAIL = 0x80004005;

Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (are you missing a cast?)

Add an explicit cast:

const int E_FAIL = (int)0x80004005;

Constant value '2147500037' cannot be converted to a 'int' (use 'unchecked' syntax to override)

Now, you have three options:

const int E_FAIL = ‭-2147467259‬;
const int E_FAIL = unchecked((int)0x80004005);
const uint E_FAIL = 0x80004005;

Using the negative values doesn't help to make things more readable. So either define all constants as unchecked((int)...) or treat HRESULT as uint.

like image 68
huysentruitw Avatar answered Sep 05 '25 04:09

huysentruitw



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!