Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29383 Discussions

How to call routines in DLL having DLLEXPORT from within the DLL

Kipling__Michael
Beginner
1,690 Views
I have a routine in a DLL which uses DLLEXPORT to make it available to routines outside the DLL. How can I call the same routine from other routines that are in the same dll? This results in an unresolved external symbol presently.

Thanks,
Mike
0 Kudos
14 Replies
Steven_L_Intel1
Employee
1,690 Views
This suggests an error in your coding. The DLLEXPORT should not affect this. If you have used ATTRIBUTES directives to change the routine naming or calling convention, you need to make sure the same directives are visible to the caller. Ideally, you'll have these routines in a module and you can just USE the module. You will get linker informational messages about local definition of imported symbol, but you can ignore that.
0 Kudos
Kipling__Michael
Beginner
1,690 Views
This suggests an error in your coding. The DLLEXPORT should not affect this. If you have used ATTRIBUTES directives to change the routine naming or calling convention, you need to make sure the same directives are visible to the caller. Ideally, you'll have these routines in a module and you can just USE the module. You will get linker informational messages about local definition of imported symbol, but you can ignore that.

The Fortran routine in the DLL with the DLLEXPORT is being called by a C routine in another DLL. I am using the ATTRIBUTES DECORATE, ALIAS to set the routine name to lowercase. The Fortran routines are not in amodule. How do I "make sure the same directives are visible to the caller"?
0 Kudos
Steven_L_Intel1
Employee
1,690 Views
You said that the problem was calling these routines from the same DLL. Is the caller a Fortran routine in this case? If so, you need the same ATTRIBUTES directive in the caller so that it knows you have changed the name of the called routine.
0 Kudos
Kipling__Michael
Beginner
1,690 Views
You said that the problem was calling these routines from the same DLL. Is the caller a Fortran routine in this case? If so, you need the same ATTRIBUTES directive in the caller so that it knows you have changed the name of the called routine.

Yes, the caller routine also in the same DLL is Fortran.

Here is example code for both routines:

SUBROUTINE Func1()
!DEC$ ATTRIBUTES DECORATE, ALIAS:'func1' :: FUNC1
!DEC$ ATTRIBUTES DLLIMPORT :: FUNC1
END SUBROUTINE FUNC1

SUBROUTINE FUNC2()
CALL FUNC1
END SUBROUTINE FUNC2

I tried adding !DEC$ ATTRIBUTES, ALIAS:'func1' :: FUNC1 to FUNC2, but it did not help.

Mike

0 Kudos
Steven_L_Intel1
Employee
1,690 Views
You forgot DECORATE.
0 Kudos
Kipling__Michael
Beginner
1,690 Views
You forgot DECORATE.

I left it out, because when I had tried it, I got the following error.

error #7794: Only a function or subroutine subprogram may have the !DEC$ ATTRIBUTES directive DECORATE specifier.

Mike
0 Kudos
Steven_L_Intel1
Employee
1,690 Views
Hmm - try adding EXTERNAL FUNC1 before the !DEC$ ATTRIBUTES (and put the DECORATE in).
0 Kudos
Kipling__Michael
Beginner
1,690 Views
Hmm - try adding EXTERNAL FUNC1 before the !DEC$ ATTRIBUTES (and put the DECORATE in).

It made no difference, I still get the same error when including DECORATE.

I can always duplicate the routine with a different name to call from within the DLL, but I was looking for something a little more elegant.

BTW, there's a typo in Func1. The DLLIMPORT should be DLLEXPORT.

Mike
0 Kudos
Steven_L_Intel1
Employee
1,690 Views
Please paste the actual code you're using that gets an error with DECORATE. I don't need to see the executable part except where it calls the routine. Working from paraphrases is always risky.
0 Kudos
Kipling__Michael
Beginner
1,690 Views
Please paste the actual code you're using that gets an error with DECORATE. I don't need to see the executable part except where it calls the routine. Working from paraphrases is always risky.

Here is the top of the routine which I am trying to call:

SUBROUTINE CL_GET_LOD_HST(JERR)
!DEC$ ATTRIBUTES DECORATE, ALIAS:'cl_get_lod_hst' :: CL_GET_LOD_HST
!DEC$ ATTRIBUTES DLLEXPORT :: CL_GET_LOD_HST


Here is the code from the caller routine:

SUBROUTINE CL_RETRV_PAIR(TA_TAG, PAIR_TYPE, NO_GEARS,
* GEAR_TAG, NO_CUTTERS, CUTTER_TAG, JERR)

EXTERNAL CL_GET_LOD_HST
!DEC$ ATTRIBUTES DECORATE, ALIAS:'cl_get_lod_hst' :: CL_GET_LOD_HST

Mike
0 Kudos
Steven_L_Intel1
Employee
1,690 Views
Hmm - I thought that would have worked. Ok, use this instead (replace the EXTERNAL and the ATTRIBUTES directive:

[plain]      INTERFACE
        SUBROUTINE CL_GET_LOD_HST (JERR)
!DEC$ ATTRIBUTES DECORATE, ALIAS:'cl_get_lod_hst' :: CL_GET_LOD_HST
        INTEGER JERR
        END SUBROUTINE CL_GET_LOD_HST
      END INTERFACE[/plain]

0 Kudos
Kipling__Michael
Beginner
1,690 Views
Hmm - I thought that would have worked. Ok, use this instead (replace the EXTERNAL and the ATTRIBUTES directive:

[plain]      INTERFACE
        SUBROUTINE CL_GET_LOD_HST (JERR)
!DEC$ ATTRIBUTES DECORATE, ALIAS:'cl_get_lod_hst' :: CL_GET_LOD_HST
        INTEGER JERR
        END SUBROUTINE CL_GET_LOD_HST
      END INTERFACE[/plain]


0 Kudos
Kipling__Michael
Beginner
1,690 Views
Quoting - Mike K


Thanks Steve. That fixed it. I have been adding interface blocks for C routines called by the Fortran routines, but had not tried it for Fortran calling Fortran.

Mike
0 Kudos
Steven_L_Intel1
Employee
1,690 Views
In general, you shouldn't write interface blocks for Fortran code - the Fortran code should be in a module that you USE. But it will get you going in a pinch.
0 Kudos
Reply