0
0

Hi, sorry for my english, i’am french… 😕

I’m trying to use the setCallbackmethod, on execution i have an error :

Error :

An unhandled exception of type ‘System.Runtime.InteropServices.MarshalDirectiveException’ occurred in playstream.exe

Additional information: Impossible de marshaler parameter #1 : la définition du type pour ce champ ne contient aucune information de disposition.

Source code :

{

channel.setCallback(FMOD.CHANNEL_CALLBACKTYPE.END,endcallback,0);

}

private static FMOD.CHANNEL_CALLBACK endcallback = new FMOD.CHANNEL_CALLBACK(EndOfStream);

private static FMOD.RESULT EndOfStream (ref FMOD.Channel channel, FMOD.CHANNEL_CALLBACKTYPE type,
int sizebytes, uint bytesread,
uint userdata)
{

return FMOD.RESULT.OK;
}

I don’t understand…

  • You must to post comments
0
0

im getting the same error:

System.Runtime.InteropServices.MarshalDirectiveException: Can not marshal parameter #1: The type definition of this type has no layout information.
at FMOD.Channel.FMOD_Channel_SetCallback(IntPtr channel, CHANNEL_CALLBACKTYPE type, CHANNEL_CALLBACK callback, Int32 command)
at FMOD.Channel.setCallback(CHANNEL_CALLBACKTYPE type, CHANNEL_CALLBACK callback, Int32 command) in fmodapi40028win\api\csharp\fmod.cs:line 2659

at that line in the c# fmod wrapper code is:

[code:3oz9f79f]return FMOD_Channel_SetCallback(channelraw, type, callback, command);
[/code:3oz9f79f]

  • You must to post comments
0
0

after some research, i have found the issue in the fmod c# wrapper code

[code:3brbd6ml]public delegate RESULT CHANNEL_CALLBACK (ref Channel channel,
CHANNEL_CALLBACKTYPE type,
int command, uint
commanddata1, uint
commanddata2);[/code:3brbd6ml]

the first argument here is the problem. bascially, the problem here is that the callback is returning the internal IntPtr representation, and not a proper C# FMOD.Channel object — also, because the callback is being passed directly to the unmanaged code, it wont be ref counted properly and will most likely screw up the GC, usually ending in a memory corruption crash.

this is my fix for the callback above, i havent looked into it futhur to see if other callbacks exist:

[code:3brbd6ml]— fmod.cs 2005-05-09 17:59:58.000000000 -0400
+++ fmod.cs 2005-06-06 00:22:03.829625000 -0400
@@ -5,6 +5,7 @@
/* ========================================================================================== */

using System;
+using System.Collections;
using System.Text;
using System.Runtime.InteropServices;

@@ -1169,7 +1170,11 @@
/*
FMOD Callbacks
*/
– public delegate RESULT CHANNEL_CALLBACK (ref Channel channel, CHANNEL_CALLBACKTYPE type, int command, uint commanddata1, uint commanddata2);
+ public delegate RESULT CHANNEL_CALLBACK (Channel channel,
+ CHANNEL_CALLBACKTYPE type,
+ int command, uint
+ commanddata1, uint
+ commanddata2);

 public delegate RESULT FILE_OPENCALLBACK     (string name, int unicode, ref uint filesize, ref IntPtr handle, ref IntPtr userdata);
 public delegate RESULT FILE_CLOSECALLBACK    (IntPtr handle, IntPtr userdata);

@@ -2654,10 +2659,43 @@
{
return FMOD_Channel_GetLevels(channelraw, levels, ref numlevels);
}
+
+ Hashtable callbacksInProgress = new Hashtable();
public RESULT setCallback (CHANNEL_CALLBACKTYPE type, CHANNEL_CALLBACK callback, int command)
{
– return FMOD_Channel_SetCallback(channelraw, type, callback, command);
+ tmpcallback tmp =
+ new tmpcallback(callback, this, callbacksInProgress);
+
+ rawCallback rcb = new rawCallback(tmp.rawCallbackHandler);
+
+ this.callbacksInProgress.Add(callback, rcb);
+
+ return FMOD_Channel_SetCallback(channelraw, type, rcb, command);
}
+
+
+ class tmpcallback {
+ CHANNEL_CALLBACK _cb;
+ Channel _channel;
+ Hashtable _hash;
+ public tmpcallback(CHANNEL_CALLBACK cb, Channel channel, Hashtable hash) {
+ _cb = cb;
+ _channel = channel;
+ _hash = hash;
+ }
+
+ public RESULT rawCallbackHandler(IntPtr rawChannel, CHANNEL_CALLBACKTYPE type, int command, uint commanddata1, uint commanddata2)
+ {
+ if (rawChannel == _channel.getRaw()) {
+ _hash.Remove(_cb);
+ return _cb(_channel, type, command, commanddata1, commanddata2);
+ }
+ return RESULT.OK;
+ }
+ }
+
+ private delegate RESULT rawCallback(IntPtr rawChannel, CHANNEL_CALLBACKTYPE type, int command, uint commanddata1, uint commanddata2);
+
public RESULT getDSPHead (ref DSP dsp)
{
RESULT result = RESULT.OK;
@@ -2813,7 +2851,7 @@
[DllImport (VERSION.dll)]
private static extern RESULT FMOD_Channel_GetLevels (IntPtr channel, [MarshalAs(UnmanagedType.LPArray)] float[] levels, ref int numlevels);
[DllImport (VERSION.dll)]
– private static extern RESULT FMOD_Channel_SetCallback (IntPtr channel, CHANNEL_CALLBACKTYPE type, CHANNEL_CALLBACK callback, int command);
+ private static extern RESULT FMOD_Channel_SetCallback (IntPtr channel, CHANNEL_CALLBACKTYPE type, rawCallback callback, int command);
[DllImport (VERSION.dll)]
private static extern RESULT FMOD_Channel_SetPosition (IntPtr channel, uint position, TIMEUNIT postype);
[DllImport (VERSION.dll)]
[/code:3brbd6ml]

  • You must to post comments
0
0

Thanks for picking that up nirva 😀

I’ve updated the delegate so that it now just returns the raw pointer, which the user can wrap up again with Channel.setRaw() within the callback.

  • You must to post comments
Showing 3 results
Your Answer

Please first to submit.