FMOD 2.02 C# Dynamic Link Issue

Attempting to load FMOD Engine Core 2.02.04 from Monogame 3.8 will produce the following error:

The procedure entry point ?setFadePointRamp@ChannelControl@FMOD@@QEAA?AW4FMOD_RESULT@@_KM@Z could not be located in the dynamic link library ...fmod.dll.

Followed by the System_Create method failing to find the .dll:

System.DllNotFoundException: 'Unable to load DLL 'fmod' or one of its dependencies: The specified module could not be found. (0x8007007E)'

Cannot be reproduced in FMOD 2.01, and works as expected in older versions with the same code.

Are you just using the C# wrapper to use FMOD in monogame or a 3rd party integration / loading the dlls youreslf? Also, what platform are you on?

On Windows 10, using the C# wrappers and loading the .dll’s myself like so:

[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);

and then:

LoadLibrary(System.IO.Path.GetFullPath("FMOD\\x64\\fmod.dll"));

In the directory containing your built <my_game>.exe, does FMOD\x64\fmod.dll exist as well?

Yeah, the .dll’s property in Visual Studio 2019 is set to Copy to Output Directory Always.

The second error, “Unable to load DLL…” should happen regardless of whether or not the path to the .dll exists. However, the first error, “The procedure entry point…” occurs after locating the .dll, at which point something’s going wrong.

The same process + code works fine on older versions of FMOD (I’ve switched to 2.01 for now to continue development).

Good point, I have not been able to reproduce that first error though. When you get a chance, can you please try using the logging lib and setting a debug callback? i.e

public static void ERRCHECK(FMOD.RESULT result)
{
    if(result != FMOD.RESULT.OK)
    {
        Console.WriteLine(result);
    }
}

static FMOD.RESULT DebugCallback(DEBUG_FLAGS flags, IntPtr filePtr, int line, IntPtr funcPtr, IntPtr messagePtr)
{
    FMOD.StringWrapper file = new FMOD.StringWrapper(filePtr);
    FMOD.StringWrapper func = new FMOD.StringWrapper(funcPtr);
    FMOD.StringWrapper message = new FMOD.StringWrapper(messagePtr);

    Console.WriteLine(String.Format("[FMOD] {0} {1} {2}", line, (string)func, (string)message));

    return FMOD.RESULT.OK;
}

...
    ERRCHECK(Factory.System_Create(out FMOD.System system));
    ERRCHECK(system.init(32, INITFLAGS.NORMAL, IntPtr.Zero));
    ERRCHECK(Debug.Initialize(DEBUG_FLAGS.LOG, DEBUG_MODE.CALLBACK, DebugCallback));
...

Just to see if there’s any more info we can get on what’s going wrong.

Unfortunately the debug callback only picks up the System.DllNotFoundException, since that exception’s the immediate result of the first error occurring.

Here’s how the first error appears to me:
fmod_entrypoint_error

Followed then by the result of the debug callback:

Unhandled exception. System.DllNotFoundException: Unable to load DLL 'fmod' or one of its dependencies: The specified module could not be found. (0x8007007E)
   at FMOD.Factory.FMOD5_System_Create(IntPtr& system, UInt32 headerversion)
   at FMOD.Factory.System_Create(System& system) in C:\...\FMOD\fmod.cs:line 902
   at ....Sound.FMODManager.Init() in C:\...FMODManager.cs:line 51
   at ....Engine.Initialize() in C:\...Engine.cs:line 144
   at Microsoft.Xna.Framework.Game.DoInitialize()
   at Microsoft.Xna.Framework.Game.Run(GameRunBehavior runBehavior)
   at ....Program.Main() in C:\....Program.cs:line 19

C:\...exe (process 57292) exited with code 0.

Really sorry this couldn’t be more helpful, I know this doesn’t give you much to go on. If there’s any way to provide you with more detailed logging let me know. Appreciate all the help you’ve given so far!

Thanks for the extra info. One thing I’m not sure of is your explicit dll loading in the LoadLibrary method- there shouldn’t be any need to load it yourself as long as you’ve set the dll to something other than “Do not Copy”.
In the fmod.cs wrapper, do you include the path to your dll in the version info? i.e:

    public partial class VERSION
    {
        public const int    number = 0x00020204;
#if !UNITY_2019_4_OR_NEWER
        public const string dll    = "FMOD\\x64\\fmodL"; // As opposed to the default of "fmodL"
#endif
    }

Loading the .dll works both ways, either explicitly loading the unmanaged dll or by setting the relative path from inside the C# wrapper’s version info.

The reason I prefer the former method over the latter is because, in the case of updating the C# wrappers to a newer/older version, I would not have to change the code inside the wrapper itself. Easy to drop in new wrappers without changing any code.

I still haven’t been able to reproduce this issue, would it be possible to get a reproduction from you when you get a chance? I don’t need a full game, just an empty or stripped down project that throws this error when running would be enough for me to investigate.