- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Thanks,
Mike
Link Copied
14 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
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"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You forgot DECORATE.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm - try adding EXTERNAL FUNC1 before the !DEC$ ATTRIBUTES (and put the DECORATE in).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
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]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page