-
Notifications
You must be signed in to change notification settings - Fork 644
sizeof being called on struct in unsafe context #406
Comments
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 So you should report this bug to Unity, the patch is really small, so they could integrate it easily. |
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. |
@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 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:
|
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, [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 ! |
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."
The text was updated successfully, but these errors were encountered: