Skip to content
This repository has been archived by the owner on Mar 30, 2019. It is now read-only.

sizeof being called on struct in unsafe context #406

Closed
augiem opened this issue Jun 2, 2014 · 4 comments
Closed

sizeof being called on struct in unsafe context #406

augiem opened this issue Jun 2, 2014 · 4 comments

Comments

@augiem
Copy link
Contributor

augiem commented Jun 2, 2014

The generated IL code for SharpDX.Interop.SizeOf calls sizeof() directly on managed structs outside an unsafe block which is not allowed. Instead it should use System.Runtime.Interop.SizeOf(). (Adding an unsafe block around sizeof instead will just cause another error "Cannot get the address of, get the size of, or declare a pointer to a managed type.")

I discovered this as I was trying to get SharpDX's DirectInput wrapper to work with the Unity3D game engine. I was always getting an exception from _ _ result _ _.CheckError() in SharpDX.DirectInput.CustomDevice.SetDataFormat. I found the cause of this was in SharpDX.DirectInput.CustomDevice.GetDataFormat, line:

_dataFormat = new DataFormat(((DataFormatAttribute) dataFormatAttributes[0]).Flags) {DataSize = Utilities.SizeOf()};

Utilities.SizeOf() was returning an incorrect value of 4 instead of 272 for the struct. When testing with a form application, it actually worked, but when tested within Unity it failed with an exception. By changing Utilities.SizeOf() to call System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), the problem was solved. I also changed the SizeOf(T[] array) overload to use Marshal.SizeOf.

Documentation:
http://msdn.microsoft.com/en-us/library/eahchzkf.aspx

"For all other types, including structs, the sizeof operator can be used only in unsafe code blocks. Although you can use the Marshal.SizeOf method, the value returned by this method is not always the same as the value returned by sizeof. Marshal.SizeOf returns the size after the type has been marshaled, whereas sizeof returns the size as it has been allocated by the common language runtime, including any padding."

@augiem augiem changed the title sizeof being called in unsafe context sizeof being called in unsafe context on struct Jun 2, 2014
@augiem augiem changed the title sizeof being called in unsafe context on struct sizeof being called on struct in unsafe context Jun 2, 2014
@xoofx
Copy link
Member

xoofx commented Jun 2, 2014

Actually, this is not related to unsafe or safe context. Using the IL sizeof is perfectly working, except that I had to do a patch around three years ago in Mono to support correctly sizeof on generic (see this issue). I believe that Unity has not this patch (because they forked Mono a long time ago. You can double check using Utilitiles.SizeOf on a Vector4 for example). Unfortunately, we cannot replace sizeof with Marshal.SizeOf, because Marshal.SizeOf is taking into account marshalling attributes which we don't want. The sizeof instruction is fast (it is actually converted to a constant), while the Marshal.SizeOf can be costly.

So you should report this bug to Unity, the patch is really small, so they could integrate it easily.

@xoofx xoofx closed this as completed Jun 2, 2014
@augiem
Copy link
Contributor Author

augiem commented Jun 2, 2014

Thanks for your reply and explaining it.

Unfortunately, there's absolutely zero chance Unity will patch their Mono distribution. The whole reason I'm trying to get SharpDX working with it is because Unity has ignored over 5 years of pleas begging for hot-plugging support for joysticks, connect/disconnect events, and a reliable way to identify a joystick by id (none of these things are functional in Unity). I (and many others) are desperate to have functional joystick support, so I started trying to use other means to get it working. SharpDX's DirectInput wrapper was perfect, and so far I'm seeing a VASTLY better joystick experience with perfect hot-plugging capabilities.

Actually I just checked all the references to Utilities.SizeOf() in my stripped down build of SharpDX (just SharpDX, SharpDX.DirectInput, and SharpDX.XInput) and it doesn't appear any of the structs contain data that should throw off the size. I'm not too concerned about the speed of Marshal.SizeOf() since this is only going to be used for DirectInput.

Thanks for creating this amazing library!

Sorry if I'm not supposed to be commenting on a closed topic. This is my first day at github.

@pbatard
Copy link

pbatard commented Aug 17, 2014

@augiem: THANK YOU!!!

I too have been banging my head against the wall, trying to figure out why Kerbal Space Program (which, unfortunately, relies Unity) couldn't get Joystick input using SharpDX.DirectInput, and concluding, after recompiling SharpDX to enable the DumpDataFormat(_dataFormat) call in CustomeDevice.cs, that the issue had to do with wrong sizes being reported for the structs.

Applying your patch suggestion worked perfectly to solve this specific issue! 👍

Copy/pasting the exception one typically gets, so that other people can find this issue more easily and don't waste as much time as I did:

SharpDXException: HRESULT: [0x80070057], Module: [General], ApiCode: [E_INVALIDARG/Invalid Arguments], Message: The parameter is incorrect.
  at SharpDX.Result.CheckError () [0x00000] in <filename unknown>:0 
  at SharpDX.DirectInput.Device.SetDataFormat (SharpDX.DirectInput.DataFormat arg0) [0x00000] in <filename unknown>:0 
  at SharpDX.DirectInput.CustomDevice`3[SharpDX.DirectInput.JoystickState,SharpDX.DirectInput.RawJoystickState,SharpDX.DirectInput.JoystickUpdate]..ctor (SharpDX.DirectInput.DirectInput directInput, Guid deviceGuid) [0x00000] in <filename unknown>:0 
  at SharpDX.DirectInput.Joystick..ctor (SharpDX.DirectInput.DirectInput directInput, Guid deviceGuid) [0x00000] in <filename unknown>:0 
  at AltInput.ProcessInput.Start () [0x00000] in <filename unknown>:0 

@pottierg
Copy link

pottierg commented Apr 1, 2016

Hello, (and sorry for the bump)

we are working our way to integrate a non-standard joystick controller in Unity using SharpDX, without success so far when it comes to put the dll into Unity (everything works well in Visual Studio).

We tried to recompile SharpDX without success. Could any of you @augiem or @pbatard upload your SharpDX library (base and DirectInput) for anyone wanting to use it with Unity?

Thank you very much,
With best regards

[EDIT] I found the libraries recompiled especially for Unity. They were initially compiled for a Kerbal Space Program add-on but you can use them for DirectInput (no XInput though).

You can find the libraries at this address: https://github.com/pbatard/AltInput

Thanks anyway !

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants