C# and fmod: Loading unmanaged c dll from resource
I've written an example project in C# how to use the fmod libary in one of your projects. I wanted to have only a executable and no further files. So I thought of adding it directly in the resources and load it when the program is started. First of all you have two options how to do it. Either use late binding and Invoke to use the functions in the Library. You could use LoadLibary(...) for that and try to use the Library directly from the memory.
Or you write the resource in your system folder so that DllImport(...) can find it. With DllImport you can easily write your own Wrapper and reuse it. I've implemented only the basic methods and enums that you need for initialisation, play, stop, looping and free so that your used memory can be allocated again. Assure on which platform your Libary was compiled. Fmod.dll that I used comes in with x86 and x64 so decide which to use and set your solution properties either on x86 or x64 otherwise you will get an missing Assembly error while compiling.
Load the dll
In order to use the dll you need to add it to your resources so you can easily access it via namespace.classname.resourcename.filename. This holds a byte[] of the file you added to your resources.
// Declare those
dllPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
dllByte = namespace.classname.resourcename.filename;</pre>
try {
FileStream stream = new FileStream(dllPath + @"\fmod.dll", FileMode.OpenOrCreate);
stream.Write(dllByte, 0, dllByte.Length);
stream.Close();
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
return false;
}
return true;
Ok we create an FileStream and write then our byte[] in the system folder. Now the DllImport - Function can find it and the user won't see the file in the running directory. DllImport doesn't allow you to specify the location where the dll is. It has a built in routine where it searchs for the dll. Only if you use your own LoadLibrary and Reflection you can specify other dirs.
Music directly from memory
Now we have the dll ready for use. Next thing is our Wrapper for the unmanaged c in the dll. C# uses managed code and you need to marshal the calls and types. Msdn provides some tutorials on that topic if you need the different types. Here is an example out of my little Wrapper class. You can find all information in the fmod documentation.
using System.Runtime.InteropServices;
[DllImport("fmod.dll")]
public static extern IntPtr FMUSIC_LoadSongEx(
IntPtr data,
int offset,
int length,
FSOUND_MODES mode,
ref int samplelist,
int samplelistnum
);
This is the tricky part with loading the music file directly from the memory. We have to hand over a Pointer with the location of the data. Therefore we need the Marshal class. We need to allocate memory and then write our data of the music file in there. Ok we gonna look at this:
// Declare this byte[] modeByte; // music file from the res IntPtr buffer = Marshal.AllocHGlobal(modByte.Length); // allocate free memory Marshal.Copy(modByte, 0, buffer, modByte.Length); //copy our data in there
IntPtr is now a pointer on our file in the memory. Now we can use our FMUSIC_LoadSongEx
IntPtr modFile = FMUSIC_LoadSongEx(buffer, 0, modByte.Length, FSOUND_MODES.FSOUND_LOADMEMORY | FSOUND_MODES.FSOUND_NORMAL, ref sentencelist, 0);
which returns use a handle which we can use to play the sound. For further information just look in the FMOD.cs and Sound.cs provided with this article. All other functions are pretty simple to use and explained in the Sound.cs
Download the example project here: FmodTutorial for Visual Studio 2008
Oktober 16th, 2009
Hello from Russia!
Can I quote a post in your blog with the link to you?
Oktober 16th, 2009
Sure, feel free to use our posts, if you give us credit.
November 17th, 2009
Download the example link is broken…
please repairing link plz..ioi
November 17th, 2009
link is updated
November 20th, 2009
great!
thx for your update