Jump to content

crush in UnigineLogic.cs


photo

Recommended Posts

Posted

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

Posted

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
×
×
  • Create New...