Callback delegates being collected?(正在收集回调代表?)
问题描述
一直在使用 FMOD 进行 C# 游戏开发,但我很早就遇到了一个似乎无法解决的问题.我想做一些分支音频的东西并将一些游戏动作同步到节拍等,所以我尝试将同步点添加到我的音乐曲目中.代码如下:
Been messing around with FMOD for C# game development and I've hit a snag early on that I can't seem to get around. I want to do some branching audio stuff and sync some gameplay action to beats and such, so I've tried adding syncpoints to my music tracks. Here's code:
public class Music
{
private Sound music;
private Channel channel;
private IntPtr syncPtr;
public string File { get; private set; }
public Music(string file)
{
File = file;
}
public void Load()
{
music = new Sound();
Audio.System.createSound(File, MODE.HARDWARE, ref music);
}
public void Unload()
{
music.release();
}
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(channelCallback);
}
private RESULT channelCallback(IntPtr channelraw, CHANNEL_CALLBACKTYPE type, IntPtr commanddata1, IntPtr commanddata2)
{
if (type == CHANNEL_CALLBACKTYPE.SYNCPOINT)
Console.WriteLine("sync!");
return RESULT.OK;
}
}
然后……
m = new Music(MUS_TUTORIAL); //m is static
m.Load();
m.Play();
歌曲加载并播放良好...直到它达到我添加的 500 毫秒同步点.此时,VC# 从 FMOD.EventSystem.update() 中吐出以下错误:
The song loads and plays fine... until it hits that 500ms syncpoint I added. At this point, VC# spits out the following error from within FMOD.EventSystem.update():
对类型为垃圾收集的委托进行了回调'游戏!FMOD.CHANNEL_CALLBACK::Invoke'.这可能会导致应用程序崩溃、损坏和数据丢失.将委托传递给非托管代码时,它们必须由托管应用程序,直到保证它们永远不会被调用.
A callback was made on a garbage collected delegate of type 'Game!FMOD.CHANNEL_CALLBACK::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.
所以不知何故,FMOD 正在丢失我通过它的委托.保存委托的 Music 实例尚未被垃圾收集 - 我现在将它存储在静态变量中 - 但我也尝试过使用静态方法无济于事.如果我禁用 CallbackOnCollectedDelegate MDA,则错误将变为空引用异常,因此 MDA 没有弄错.我想我一定不能完全理解 FMOD 在这里做什么.
So somehow FMOD is losing track of the delegate I passed it. The Music instance that holds the delegate has not been garbage collected - I'm storing it in a static variable for now - but I've tried with a static method too to no avail. If I disable the CallbackOnCollectedDelegate MDA the error becomes a null reference exception, so the MDA isn't mistaken. I assume I must just not fully understand what FMOD is doing here.
是否有任何 C# + FMOD 大师能够看到我的错误?
Are any C# + FMOD gurus able to see my mistake?
推荐答案
channel.setCallback(channelCallback);
这就是问题陈述.FMod 是非托管代码.您在此处创建一个委托对象并将其传递给非托管代码.问题是,垃圾收集器无法跟踪本机代码持有的引用.下一次垃圾回收将找到对象的 no 引用并收集它.当本机代码进行回调时 Kaboom.
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);
}
您需要从 FMod 包装器代码中找到实际的委托类型,我只是猜测SomeDelegateType".
You need to find the actual delegate type from the FMod wrapper code, I merely guessed at "SomeDelegateType".
这篇关于正在收集回调代表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:正在收集回调代表?
- 输入按键事件处理程序 2022-01-01
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- 如何用自己压缩一个 IEnumerable 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
