Jump to content

crush in UnigineLogic.cs


photo

Recommended Posts

Hello

I trying to call c# function from unigine script :

here main function that initializes costum worldLogic ( initializes costum hirachy structure from HUGE *.node file )

		public static void TestCallFunc() {	Log.message("TestCallFunc\n");	}

		static void Main(string[] args)	{
			Wrapper.init();

			Engine engine = Engine.init(Engine.VERSION, args);
			ControlLogic.SetUnigineApp(App.get());
			AppWorldLogic worldLogic = new AppWorldLogic();

			Interpreter.addExternFunction("TestCallFunc", new Interpreter.Function0(TestCallFunc));
			Log.message("Interpreter.addExternFunction {0}\n",App.get());

			engine.main(null, worldLogic, null);// here error occurs

			Engine.shutdown();
		}
   public class AppWorldLogic : WorldLogic {
        // World logic, it takes effect only when the world is loaded.
        // These methods are called right after corresponding world script's (UnigineScript) methods.
        public AppWorldLogic(){ Log.message("AppWorldLogic constr\n"); }

        public override int init(){
            Log.message("AppWorldLogic.init()\n");
            // Write here code to be called on world initialization: initialize resources for your world scene during the world start.

            DictionaryClass.ReadFromFile("TreeDictionary.txt");
            IssTreeVM.FillIssTree();
		ControlLogic.init_ui();

            return 1;
	}//-----in debug step-bystep, error message popup after this line
   ....

if I remove "Interpreter.addExternFunction("TestCallFunc"" - or - comment "TestCallFunc();" callback from unigine script - all goes fine !

else it crushes with useless details in search for file "d:\BuildAgent\work\32ae776d4ea36e16\source\csharp\library\UnigineLogic.cs"

any notes to solve it?

fail_pic.png

Link to comment

Hi Mikhail,

I've successfully reproduced this crash.
It happens because garbage collector at some point destroys delegate that you pass to the Interpterer.
I'll have this fixed.

As a workaround, you can use this code:

var callback = new Interpreter.Function0(TestCallFunc);
GCHandle handle = GCHandle.Alloc(callback);
Interpreter.addExternFunction("TestCallFunc", callback);

And if you're planning to add a lot of functions, you can write something like this:

class DelegatePinner : IDisposable
{
	private List<GCHandle> handles;

	public DelegatePinner()
	{
		handles = new List<GCHandle>();
	}

	public T pin<T>(T func)
	{
		if (func != null)
			handles.Add(GCHandle.Alloc(func));
		return func;
	}

	public void Dispose()
	{
		foreach (var h in handles)
			h.Free();
	}
};

...

using (DelegatePinner pinner = new DelegatePinner())
{
	Interpreter.addExternFunction("func0", pinner.pin(new Interpreter.Function0(func0)));
	Interpreter.addExternFunction("func1", pinner.pin(new Interpreter.Function0(func1)));
	Interpreter.addExternFunction("func2", pinner.pin(new Interpreter.Function0(func2)));

	engine.main(null, worldLogic, null);

	Engine.shutdown();
}

 

  • Like 1
Link to comment
×
×
  • Create New...