SiGetEvent

Post questions, comments and feedback to our 3Dconnexion Windows Development Team.

Moderator: Moderators

Post Reply
Merlin978
Posts: 2
Joined: Thu May 16, 2019 5:10 am

SiGetEvent

Post by Merlin978 »

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?
ngomes
Moderator
Moderator
Posts: 3321
Joined: Mon Nov 27, 2006 7:22 am
Contact:

Re: SiGetEvent

Post by ngomes »

Hi Merlin978 ,

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);
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#.
Nuno Gomes
Merlin978
Posts: 2
Joined: Thu May 16, 2019 5:10 am

Re: SiGetEvent

Post by Merlin978 »

Hi.

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
But he throws me out an error, because the marshalAs is not declared.

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
ngomes
Moderator
Moderator
Posts: 3321
Joined: Mon Nov 27, 2006 7:22 am
Contact:

Re: SiGetEvent

Post by ngomes »

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.
Post Reply