I'm implementing C# wrapper to link C-library and having trouble passing Enum value as parameter to Unmanaged function call which takes pointer as input. that is throwing this exception. The code looks like this :
Function from library :
int function(infoField Field, void const *value);
Marshal in C#:
[DllImport("CLibrary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int function(infoField Field, IntPtr value);
infoField structure :
public enum infoField {section, options, orientation};
One Enum type 'Options' has 4 values to choose from :
public enum Options { var1, var2, var3, var4};
I want to pass one of the 4 choices as value for EnumField = Options, something like this:
IntPtr value = (Intptr)Options.var1;
function (infoField.options, value);
I think I am missing correct cast convention for pointer to point to Enum type. What should be correct format to pass enum value with IntPtr to function? So far, I have tried few options but get AccessViolationException on function call, Which either means memory allocation failed or did not match what what library is expects the type.
PS : Function marshaling is successful for Other EnumFields. That's also because value passing is string value for them. But Particularly for 'options' it has to be one of 4 Enum options.
Normally, C++
enumerators are defined as follows:
enum class ENUM_FIELD
{
VAR1,
VAR2,
VAR3,
VAR4
};
By default, enum class types are int
sized, which means that you can translate them to C#
as follows:
public enum EnumField
{
VAR1,
VAR2,
VAR3,
VAR4
}
In such case, both enums will be mapped without problem within the interop environment. But if the C++
enum is defined in a different way, or if the unmanaged method requires a different type, you may need to change the underlying type in your C#
declaration in order to map the values correctly. For example:
public enum EnumField : short
{
VAR1,
VAR2,
VAR3,
VAR4
}
Anyway, I think the problem is not caused by the enum, but rather by what you pass as the const void*
parameter. Casting an enum value to IntPtr
doesn't look right to me:
UInt32 field = (UInt32)EnumField.VAR1;
GCHandle handle = GCHandle.Alloc(field, GCHandleType.Pinned);
IntPtr ptr = handle.AddrOfPinnedObject();
// pass the ptr variable to the unmanaged function
// and don't forget to handle.Free() when you are done