I have some C code that I compile to a dll object.
I have a separate project, written in Fortran, which I too compile to a single dll object.
I need to call a function inside the Fortran dll from the C dll, without using LoadLibrary. I also need the 2 dll to remain separate, so I can replace one or the other without re-compiling them together.
I have read some information on the topic, but I can't get it to work. The compiler does not throw errors or warnings, but when I start my main program it fails. Here's what I tried:
I have declared all functions I wish to call from the C code with
BIND ("C", NAME="FUNCNAME")
I have declared the
USE, INTRINSIC :: ISO_C_Binding
inside the functions and subroutines I intend to call from the C codeI included
!DEC$ ATTRIBUTES DLLEXPORT :: NAME
inside the Fortran code (I am using ifort)I use c type variables in my Fortran code
I pass variables by reference in the C code
I included the Fortran dll .lib file as a source file to the C project
According to most sources and docs I consulted, I should be able to simply do the following:
In Fortran:
SUBROUTINE FORTRANDLLFUNCTION(arg1, arg2, arg3, char1) BIND (C, NAME='FORTRANDLLFUNCTION')
USE, INTRINSIC :: ISO_C_Binding
IMPLICIT NONE
!DEC$ ATTRIBUTES DLLEXPORT :: FORTRANDLLFUNCTION
REAL(C_FLOAT), INTENT(INOUT) :: arg1
REAL(C_FLOAT), INTENT(INOUT) :: arg2
REAL(C_FLOAT), INTENT(INOUT) :: arg3
CHARACTER(KIND=C_CHAR), INTENT(IN ) :: char1
<do stuff>
END SUBROUTINE FORTRANDLLFUNCTION
In C:
extern void FORTRANDLLFUNCTION(float**, float**, float**, char*, int);
float a, b, c;
char abc;
FORTRANDLLFUNCTION(&a, &b, &c, abc, sizeof(abc));
However, I get an error when running the main program. If I remove the call to the Fortran function and run the main program with the compiled C dll, it works. What could be the source of my problem?
This is the output of dumpbin /exports
on the compiled Fortran dll:
And this is the result of dumpbin /imports
on the compiled C dll:
CodePudding user response:
So I finally found the cause of my problems...
I abandoned this and focused on a different part of the project, which led me to finding out that the reason why I was getting this error is that the Fortran dll didn't have to be in the same dir as the C dll, but the same dir as the exe calling the C dll (the C dll being in a different location).
It really surprises me as the error I was getting was "Can't load C.dll", instead of "Could not find/load fortran.dll", the correct traceback or message could have saved me hours...
Either ways, I believe it wouldn't have worked anyways had it not been for the comments made by @Mgetz, so thanks for that, really!
Some more clarifications to some of the comments on the question:
Before I finally realized what the solution was, and on top of creating my VS projects using cmake .. -G "Visual Studio 17 2022" -A x64
, I also performed a dumpbin /headers
on both the Fortran dll and the C dll, which both revealed that the machine was 8664 (64 bits architecture).
I use float** and int** in the Fortran dll function prototype in the C code because I call the Fortran function from within a C function which already takes pointers as arguments, so if I don't use "double pointers" when calling the Fortran function I get warnings from the compiler.
And yes, the Fortran runtime libraries were in the environment, I regularly work with Fortran, I knew that was not an issue.