tags:

views:

86

answers:

3

I'm trying to do an interop to a C++ structure from C#. The structure ( in C# wrapper) is something like this

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SENSE4_CONTEXT
{


public System.IntPtr dwIndex; //or UInt64, depending on platform.
}

The underlying C++ structure is a bit abnormal. In 32 bit OS, dwIndex must be IntPtr in order for the interop to work, but in 64 bit OS, it must be UInt64 in order for the interop to work.

Any idea how to modify the above structure to make it work on both 32 and 64 bit OS?

A: 

You could use a compiler directive/platform detect, then do a common typedef:

typedef indexType IntPtr

or

typedef indexType UInt64

Delan Azabani
No, he can't. This is C#.
SLaks
+1  A: 

In a 64-bit process, an IntPtr should be marshalled exactly the same as a UInt64.
Make sure to set your Target Platform to Any CPU.

To treat it as a UInt64 in C#, you can write

UInt64 value = (UInt64)s.dwIndex.ToInt64();

If you need to run as a 32-bit process, you'll need to declare two different versions of the struct, and two different overloads of the methods that take it, and select one of them using an if statement.

SLaks
That's the problem; an `IntPtr` should be marshalled as `UInt64`, but it's not.
Ngu Soon Hui
What's the difference? They're both eight bytes.
SLaks
Do you mean it needs to be unsigned? In that case, you can use `UIntPtr`: http://msdn.microsoft.com/en-us/library/system.uintptr%28v=VS.71%29.aspx
Dean Harding
@SLaks, there should be no difference. But I don't know why I got such a problem.
Ngu Soon Hui
What *is* the problem exactly?
Dean Harding
What's your Target Platform?
SLaks
SLaks is correct. To interop there is no difference between a UInt64 and an IntPtr on a 64 bit process.
Josh Einstein
@Josh, there *is* a difference. As my testing shows.
Ngu Soon Hui
@Ngu: What is it?
SLaks
@SLaks, the difference is that if you use `IntPtr` in place of `UInt64`, the code might fail to run.
Ngu Soon Hui
@Ngu: That does not make sense. Do you know how it is passed differently or how it fails?
SLaks
@SLaks, I don't, partly because I don't have access to the underlying C++ code.
Ngu Soon Hui
+1  A: 

If the "dw" prefix in dwIndex is accurate then it sounds like a DWORD, which is a 32-bit unsigned integer. In that case you need to use UIntPtr, which will be like UInt32 on 32-bit and like UInt64 on 64-bit.

It seems unlikely that your C++ program requires a signed integer on a 32-bit platform and an unsigned one on a 64-bit one (though not impossible, of course).

Evgeny
A `DWORD` type is a 32-bit unsigned integer regardless of whether or not the OS is 32 or 64 bit.
JaredPar