Click here to Skip to main content
15,867,308 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a c++ function which I am calling from c# using pinInvoke. Following is my cpp method-

C++
int test(DWORD verb,DWORD verb2 )
{
	return verb2 *100;
}


My function is exposed as -

C++
extern "C" {
	__declspec(dllexport) int test(DWORD verb, DWORD verb2);
}


Following is my c# code where I am calling the above method:

public class API
{
[DllImport("mydll.dll", EntryPoint = "test", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U4)]
public static extern uint test(
[MarshalAs(UnmanagedType.U8)]ulong verb,
[MarshalAs(UnmanagedType.U8)]ulong verb2
);

static void Main(string[] args)
{
uint x = DPAPI.test(26,10);
Console.Write("result is-"+x);
}
}

Here the second value is getting passed as 0,so wrong result is coming.Am I doing something wrong while passing the value?

What I have tried:

I am relatively new to Pinvoke. So I tried debugging to see whether the value is not getting passed to c++ code or whether the c++ code is not returning proper values.I found that the value getting passed itself was wrong.
Posted
Updated 25-May-17 0:44am

Quote:
[MarshalAs(UnmanagedType.U8)]ulong verb,
[MarshalAs(UnmanagedType.U8)]ulong verb2
That should be, instead
C++
[MarshalAs(UnmanagedType.U4)] uint verb,
[MarshalAs(UnmanagedType.U4)] uint verb2

or, simply:
C++
uint verb,
uint verb2
 
Share this answer
 
Comments
Pete O'Hanlon 25-May-17 8:07am    
My 5.
DSomesh 25-May-17 14:08pm    
One more similar thing came up today..So I was passing a two values(long as unamanagedtype.I8 and int as unmanagedtype.I4) and in my c++ code both values were DWORD. As per your explanation above it should not have worked. But in my case it worked properly for 64 bit machine but in case of 32 bit second value was always coming as 0. I know what I did was wrong but would like to know why it behaved that way.Care to explain this behavior?
CPallini 25-May-17 15:38pm    
You can explain it yourself: simply output sizeof(long) on both the machines.
Something you need to be aware of - DWORD depends on the Windows version. So, on a 32 bit machine, a DWORD is 32 bits. On a 64 bit machine, it's 64 bits. More importantly, a DWORD is a uint (not a ulong).

Edit: As Carlo pointed out - I was thinking of DWORD_PTR, not DWORD. However, the point about a DWORD being a uint is still valid.
 
Share this answer
 
v3
Comments
CPallini 25-May-17 7:44am    
DWORD is 32 bits, both on 32 and 64 bits machines. I suppose it is for compatibility reasons.
Pete O'Hanlon 25-May-17 8:03am    
Doh! I was thinking of DWORD_PTR. Thanks.
CPallini 25-May-17 8:27am    
It's rather confusing, in my opinion.
By the way, thank you and have my 5.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900