I trying to export one of my project to the webplayer with Unity3D. In this project I use a “GCHandle.Alloc”. In the documentation ( http://docs.unity3d.com/412/Documentation/ScriptReference/MonoCompatibility.html ) I found the compatibility “GCHandle Alloc (Object value, GCHandleType type) Search MSDN .NET 2.0 2.0 subset Web player Micro”. The “Web player” is green (supported so?).
But if I try it fail. In the IDE it works but in the browser no. I can read in the log ( \AppData\Local\Temp\UnityWebPlayer\log\ ) an exception :
test 1..
(Filename: C:/BuildAgent/work/ea95e74f6e5f192d/Runtime/ExportGenerated/WebPlayer/UnityEngineDebug.cpp Line: 54)
test 1.. GC Alloc..
(Filename: C:/BuildAgent/work/ea95e74f6e5f192d/Runtime/ExportGenerated/WebPlayer/UnityEngineDebug.cpp Line: 54)
MethodAccessException: Attempt to access a private/protected method failed.
at System.Security.SecurityManager.ThrowException (System.Exception ex) [0x00000] in <filename unknown>:0
at Testfailor.Start () [0x00000] in <filename unknown>:0
(Filename: Line: -1)
Exemple code class :
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
public class Testfailor : MonoBehaviour {
void Start () {
Debug.Log("test 1..");
List<int> arrayOfInts;
arrayOfInts = new List<int>();
arrayOfInts.Add(10);
Debug.Log("test 1.. GC Alloc..");
GCHandle.Alloc(arrayOfInts, GCHandleType.Pinned);
Debug.Log("test 1.. PASSED");
}
void Update () {
}
}
So for security reason in a browser you can’t access to the GC ? Is there a trick ? The documentation linked is obselete ? @Unity webplayer 4.2.1f4
“6.MethodAccessException: Attempt to access a private/protected method failed.”
This actually doesn’t surprise me. I’ve seen other differences with the WebPlayer Mono version (for example, the KeyedCollection base class is missing a constructor).
Out of curiosity… what’s the reason you’re wanting to pin your object? I would personally avoid it if you can as it can result in things never being properly cleaned up by the garbage collector. This is an issue that’s specific to Mono’s GC implementation… it doesn’t handle pinned objects as neatly as the .NET Native GC does.
I’m agree but the GC.Alloc is in a engine (IN2AR). The pinned object is a Color32 which contain the stream of the webcam. Thanks for your answer I will see if it is possible to get it work with the IN2AR team.
Edit: webplayer is not compatible to any plugin so…
Well my guess is that it won’t change if this is in an engine SDK. They are likely using it to pass pointers from the C# code into native C++ code. GCHandle.Aloc(obj, GCHandleType.Pinned) will actually return the pointer of that object.
Looking at your sample a little more closely I think I know what the problem is… You have “arrayOfInts” declared within your start function… then you’re calling GcHandle.Alloc(arrayOfInts, GCHandleType.Pinned) but I think what is happening is that your array is going out of scope and you’re losing it (possibly).
Try changing your code to this:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
public class Testfailor : MonoBehaviour {
public List<int> arrayOfInts;
void Start () {
Debug.Log("test 1..");
arrayOfInts = new List<int>();
arrayOfInts.Add(10);
Debug.Log("test 1.. GC Alloc..");
GCHandle.Alloc(arrayOfInts, GCHandleType.Pinned);
Debug.Log("test 1.. PASSED");
}
}
It seems that GCHandle.Alloc is simply forbidden in WebPlayers. My guess is that it’s treated as an unsafe call - no no in web builds. Makes sense: you can grab a pointer to the pinned object, so it is, technically unsafe.
A warning would be nice when switching platform. Just spent an hour figuring that one out.