I recently added a call to a C++ function embedded in a library (.lib) file to a fortran project that is then compiled into a DLL for use by C#. This had the unfortunate effect of breaking my solution (.sln), which was previously comprised of only C# and Fortran languages. My question is this: do conflicts arise if a fortran dll has to both 'export' functions for C# while simultaneously importing C++ functions contained in a .lib file? To help illustrate this question, I've laid out below the working code followed by the amended code that broke. I'll reiterate that when the .sln was working, C# was calling functions in a Fortran DLL that did not also include a C++ .lib compiled into it. For brevity, I've only shown one call from C# to fortran ("MFNWT_INIT"):
C# code:
using System; public static class CustomMODSIM { public static Model myModel = new Model(); //Fortran DLL interface [DllImport("MF_DLL.dll", CallingConvention = CallingConvention.StdCall)] public static extern void MFNWT_INIT(); //...other imported functions cut out for brevity... private static void OnInitialize() { MFNWT_INIT(); //Initialize other C# variables ... } ... }
Working Fortran DLL code:
MODULE MF_DLL C CONTAINS C SUBROUTINE MFNWT_INIT() BIND(C,NAME="MFNWT_INIT") C !DEC$ ATTRIBUTES DLLEXPORT :: MFNWT_INIT C USE GLOBAL USE GWFBASMODULE INCLUDE 'openspec.inc' C ...
Now, here are the steps I performed that broke it. As stated, I added a C++.lib file to the fortran project and compiled without any errors. The following fortran module serves as the interface between the C++.lib file and the fortran code, it was added to the Fortran project:
Module ApplicationsInterface implicit none interface ! =============================================================!! ! Two tasks are performed in this subroutine: ! 1) Create DataTable for holding "Ideal Applications" ! 2) Fill this DataTable with values stored in a CSV file generated by a VB code. ! =============================================================!! subroutine IdlAppInit() bind(C, name="idappinit") import end subroutine end interface End Module ApplicationsInterface
And finally, I amended the first bit of fortran I showed above with lines 12 & 17 below, and it broke:
MODULE MF_DLL C CONTAINS C SUBROUTINE MFNWT_INIT() BIND(C,NAME="MFNWT_INIT") C !DEC$ ATTRIBUTES DLLEXPORT :: MFNWT_INIT C USE GLOBAL USE GWFBASMODULE C USE ApplicationsInterface C INCLUDE 'openspec.inc' C ... CALL IdlAppInit() ...
The funny thing was, if I add only the USE ApplicationsInterface line, no problems, I can still step through the code in debug mode. It is only when I add line 17 ("CALL IdlAppInit()") and try to "step into" it (debug mode) from C# that I get the error message:
"An unhandled exception of type 'System.DllNotFoundException' occurred in MODSIMStreamAquifer.exe"
followed by
"Additional information: Unable to load DLL 'MF_DLL.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)"
Why doesthe MF_DLL.dll suddenly not load? Literally, it goes from working to not working if line 17 in the previous bit of fortran is commented/uncommented. I also added a screen shot of the error message to this post.