0
0

Hi!

I have downloaded FMOD Ex 4.24.05 (amazing library, by the way!) and I am facing some problems with the C# wrapper.

I don’t think it’s a bug, more probably it’s my understanding of the interaction between managed/unmanaged code. If you can shed some light on this I’ll be very grateful though.

Ok, when setting up my environment I create a DSP:

[code:3otjsnsk]
// FMOD.System initialization (using the STREAM_FROM_UPDATE and NRT modes)
...

DSP_DESCRIPTION desc = new DSP_DESCRIPTION();
desc.name = someName;
desc.channels = 0;
desc.read = new DSP_READCALLBACK(MyDSPCallback);

DSP dsp = null;
DSPConnection conn = null;
system.createDSP(ref desc, ref dsp);

// Prevent the GC from collecting the DSP
GCHandle dspHandle = GCHandle.Alloc(dsp);

system.addDSP(dsp, ref conn);

// system.update() loop
...

dspHandle.Free();
[/code:3otjsnsk]

And the read callback looks like this:

[code:3otjsnsk]
private RESULT MyDSPCallback(ref DSP_STATE state, etc.)
{
try
{
// Get a pointer to the DSP instance
IntPtr dspPtr = state.instance;

  // Try to grab the DSP object behind the pointer
  GCHandle dspHandle = GCHandle.FromIntPtr(dspPtr);
  DSP dsp = (DSP)dspHandle.Target;

  // Main DSP code...
  return RESULT.OK;

}
catch (Exception)
{
return RESULT.ERR_INTERNAL;
}
}
[/code:3otjsnsk]

I get an exception when hitting the GCHandle.FromIntPtr(dspPtr) line. The integer value of dspPtr, in the callback, is not the same as the one I get when debugging the initialization code with GCHandle.ToIntPtr(dspHandle).

Strangely, the exception is not trapped in the catch block of the callback; instead I get a System.ExecutionEngineException thrown by FMOD.System.update() (so the precise cause of the problem is masked, maybe some data corruption).

I’m stuck at this point. I thought that GCHandle’ing the DSP object would ensure that the state.instance pointer would be always valid, but it looks like I missed something. Note that I can’t pin it with GCHandle.Alloc(dsp, GCHandleType.Pinned) because the DSP is not blittable.

I can work around this by refactoring the code so I don’t need to access the DSP from the callback. Still, any help would be really appreciated!

Thanks in advance
Thomas

PS: edited to account for new findings

  • You must to post comments
0
0

Ok, my apologies, there is an example on how to do this in examples_csharp\vs200x\dsp_custom.cs:

[code:1yq0dpre]
DSP dspInstance = new DSP();

private RESULT MyDSPCallback(ref DSP_STATE state, etc.)
{
dspInstance.setRaw(state.instance);

// Do whatever you want with dspInstance :)
}
[/code:1yq0dpre]

It works fine!

Thomas

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.