Search code examples
cvisual-studiofortranintel-fortran

Name mismatch when using Fortran shared library


I managed to successfully compile a shared library using IFORT that contains some .obj files (i.e. dependencies) compiled by Visual Studio C.

When trying to use this shared library in a Fortran program it fails saying Example.obj : error LNK2019: unresolved external symbol TEST_mp_EXECUTE referenced in function MAIN__.

When I use the tool dumpbin.exe I can see that function execute is in the shared library. Any idea why this mismatch of names that is making the compilation of the Fortran program to fail?

Content of file Test.c:

__declspec(dllexport) int execute(void);

int execute(void)
{
    return 2 + 3;
}

File Test.c successfully compiled with Microsoft Visual Studio C as follows (the result is an object file named Test.obj):

cl.exe Test.c /FoTest.obj

Content of file Test.f90:

MODULE Test

    USE, INTRINSIC :: iso_c_binding, ONLY: c_int
    IMPLICIT NONE

    INTERFACE

        INTEGER(c_int) FUNCTION execute() BIND(C, name = "execute")
            USE, INTRINSIC :: iso_c_binding, ONLY: c_int
        END FUNCTION

    END INTERFACE

END MODULE

File Test.f90 successfully compiled with IFORT as follows (the result is a shared library named Test_dll.dll along with its header file named Test_dll.lib, and a Fortran module file named test.mod):

ifort.exe Test.obj /Qm64 /LD /FeTest_dll.dll

Content of file Example.f90:

PROGRAM Example

    USE test

    state = execute()

END PROGRAM

Now, when trying to compile file Example.f90 as ifort.exe Example.f90 Test_dll.lib it fails saying Example.obj : error LNK2019: unresolved external symbol TEST_mp_EXECUTE referenced in function MAIN__. Any idea what is going on?


Solution

  • Note that you have two sources that compile to a test.obj - the Fortran and the C. Also, the cl command you showed tries to generate an executable. Here's how to do it right:

    cl /c /MD /Foctest.obj test.c
    ifort /dll test.f90 ctest.obj
    ifort example.f90 test.lib
    

    I added /MD to the C compile to get a compatible set of run-time libraries. This generated the executable without errors.