Hi
I am using Microsoft Visual Studio 15 VB.NET, the product SpaceTraveler/Space Navigator and I have a problem with the function SiGetEvent.
I always get a System.AcessViolationexception or "the arraytype of siEvent is not the correct type"-Error. Can you send me of the siEvent the whole structure-Form in VB.NET (not C++) and an instruction how I should declare it?
SiGetEvent
Moderator: Moderators
Re: SiGetEvent
Hi Merlin978 ,
We have a C# sample in the SDK, the TestSiapp program. The function SiGetEvent is declared as follows:
For all the details, including the class definition for the custom marshaller, please refer to the Siapp.cs file.
Since VB is also managed, I believe you take the same approach as we have for C#.
We have a C# sample in the SDK, the TestSiapp program. The function SiGetEvent is declared as follows:
Code: Select all
[DllImport(SI_DLL)]
public static extern SpwRetVal SiGetEvent([In] IntPtr hdl, int flags, [In] SiGetEventData pData, [In, Out] [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SiSpwEventMarshaler))] SiSpwEvent spwEvent);
Since VB is also managed, I believe you take the same approach as we have for C#.
Nuno Gomes
Re: SiGetEvent
Hi.
I tryed to write something similar to yours.
But he throws me out an error, because the marshalAs is not declared.
How to convert this into VB.NET?
I tryed to write something similar to yours.
Code: Select all
<DllImport("SiAppDll.dll")>
Public Shared Function SiGetEvent(<[In]()> ByVal SiHdl As IntPtr, ByVal flags As Integer, <[In]()> ByRef pData As SiGetEventData,
<[In](), [Out](), MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = TypeOf (SiSpwEventMarshaler) > ByRef pEvent As SiSpwEvent) As SpwRetVal
End Function
How to convert this into VB.NET?
Code: Select all
#region Custom marshalers
public class SiSpwEventMarshaler : ICustomMarshaler
{
private IntPtr nativeData = IntPtr.Zero;
private SiSpwEvent siSpwEvent = null;
public IntPtr MarshalManagedToNative(object managedObj)
{
nativeData = Marshal.AllocHGlobal(GetNativeDataSize());
if (managedObj != null)
{
siSpwEvent = (SiSpwEvent)managedObj;
Marshal.WriteInt32(nativeData, (int)siSpwEvent.type);
}
return nativeData;
}
public object MarshalNativeToManaged(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero)
siSpwEvent.u = null;
if (nativeData != pNativeData)
throw new MarshalDirectiveException("Marshaling different structure back to managed data");
SiEventType type = (SiEventType)Marshal.ReadInt32(pNativeData);
switch (type)
{
case SiEventType.SI_APP_EVENT:
siSpwEvent.u = (SiEventData)Marshal.PtrToStructure(pNativeData, typeof(SiAppCommandData));
break;
case SiEventType.SI_BUTTON_EVENT:
case SiEventType.SI_MOTION_EVENT:
case SiEventType.SI_ZERO_EVENT:
siSpwEvent.u = (SiEventData)Marshal.PtrToStructure(pNativeData, typeof(SiSpwEventData));
break;
case SiEventType.SI_BUTTON_PRESS_EVENT:
case SiEventType.SI_BUTTON_RELEASE_EVENT:
siSpwEvent.u = (SiEventData)Marshal.PtrToStructure(pNativeData, typeof(SiHWButtonData));
break;
case SiEventType.SI_CMD_EVENT:
siSpwEvent.u = (SiEventData)Marshal.PtrToStructure(pNativeData, typeof(SiCmdEventData));
break;
case SiEventType.SI_DEVICE_CHANGE_EVENT:
siSpwEvent.u = (SiEventData)Marshal.PtrToStructure(pNativeData, typeof(SiDeviceChangeEventData));
break;
default:
siSpwEvent.u = null;
break;
}
return siSpwEvent;
}
public void CleanUpNativeData(IntPtr pNativeData)
{
Marshal.FreeHGlobal(pNativeData);
pNativeData = IntPtr.Zero;
}
public void CleanUpManagedData(object managedObj)
{
}
public int GetNativeDataSize()
{
return 4 + SI_KEY_MAXBUF;
}
public static ICustomMarshaler GetInstance(string cookie)
{
return new SiSpwEventMarshaler();
}
}
#endregion Custom marshalers
Re: SiGetEvent
We do not have that code but Microsoft has very detailed documentation on ICustomMarshaler. Make sure you pick "VB" from the menu towards the top of that page to switch to the VB examples.