Callback delegates being collected?

梦想与她 提交于 2019-11-28 11:56:42
    channel.setCallback(channelCallback);

That's the problem statement. FMod is unmanaged code. You are creating a delegate object here and passing it to the unmanaged code. Problem is, the garbage collector cannot track references held by native code. The next garbage collection will find no references to the object and collect it. Kaboom when the native code makes the callback.

You need to keep a reference yourself so this won't happen:

public class Music
{
    private SomeDelegateType callback
    //...
    public Music(string file)
    {
        File = file;
        callback = new SomeDelegateType(channelCallback);
    }

    public virtual void Play()
    {
        Audio.System.playSound(channel == null ? CHANNELINDEX.FREE : CHANNELINDEX.REUSE, music, false, ref channel);
        music.addSyncPoint(500, TIMEUNIT.MS, "wooo", ref syncPtr);
        channel.setCallback(callback);
    }

You need to find the actual delegate type from the FMod wrapper code, I merely guessed at "SomeDelegateType".

I had a similar problem between VB.NET and a custom C++ DLL. Fixed thanks to @Hans. I owe this site many times over for all the problems it's got me through. Adding my problem+solution in hopes it helps others seeing the same solution in a different context.

Declared this (in a module)

Public Delegate Sub CB_FUNC(ByVal x As Integer, ByVal y As Integer)
Public Declare Sub vidProc_cb_MouseClick Lib "C:\Users\.....\vidProc\product\vidProc.dll" (ByVal addr_update As CB_FUNC)

Originally:

Had a simple call in a button_click sub:

vidProc_cb_MouseClick(AddressOf updateXY)

I would get the 'CallbackOnCollectedDelegate' error. Not immediately, but after interacting with other objects on the form, then trying to invoke the callback (which in my case was a mouse click in an OpenCV window).

Fixed by:

1) Declaring (in the Form Class, Declarations)

Private addr_update As CB_FUNC

2) Defining addr_update on Form Load

addr_update = New CB_FUNC(AddressOf updateXY)

3) Calling my 'set callback' function with the new pointer (in the button_click sub)

vidProc_cb_MouseClick(addr_update)

I think I understood @Hans and implemented it correctly (I can't reproduce the error). Hope this helps someone.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!