- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a FORTRAN DLL that is integrated into third-party software. To do this, it has one entry point routine, the arguments to that routine contain the addresses of all the other interface routines. References to these interface routines are resolved in a C library, which I believe is unneccessary. According to my predecessor (who came up with this scheme), the C library:
"Contains the definition of the addresses of imported functions in the DLL libraries. These addresses
correspond to addresses of functions in whichever executable program calls
the DLL library. To avoid using the DLLIMPORT compiler directive in the
DLL, the addresses are used to call the functions directly. This permits
the building of the DLLs without using any import directives, and thus
does not require a formal exports declaration from the calling executable.
The set of required functions are also defined here. These are called using the
aforementioned addresses."
To improve maintainability, I think I can replace the C with FORTRAN using the POINTER keyword - but I'm not sure exactly how - any one want to help me out?
Cheers,
Dan
"Contains the definition of the addresses of imported functions in the DLL libraries. These addresses
correspond to addresses of functions in whichever executable program calls
the DLL library. To avoid using the DLLIMPORT compiler directive in the
DLL, the addresses are used to call the functions directly. This permits
the building of the DLLs without using any import directives, and thus
does not require a formal exports declaration from the calling executable.
The set of required functions are also defined here. These are called using the
aforementioned addresses."
To improve maintainability, I think I can replace the C with FORTRAN using the POINTER keyword - but I'm not sure exactly how - any one want to help me out?
Cheers,
Dan
Link Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Mmh, it's still not so clear what that C library did -- could you post/attach some fragments?
It's the use of word "import" that confuses me -- I'd rather expect "export". On the second reading, it looks as if calling .exe offers some callback functions that are to be called back from the dll, but I'm not sure.
If I got it right, see for example function prototypes and MAPIBind routine in MAPI module. MAPIBind dereferences routine pointers to callable routines. It uses GetProcAddress to obtain the addresses, but they may come through arg-list as well, as (I believe) in your case.
Jugoslav
It's the use of word "import" that confuses me -- I'd rather expect "export". On the second reading, it looks as if calling .exe offers some callback functions that are to be called back from the dll, but I'm not sure.
If I got it right, see for example function prototypes and MAPIBind routine in MAPI module. MAPIBind dereferences routine pointers to callable routines. It uses GetProcAddress to obtain the addresses, but they may come through arg-list as well, as (I believe) in your case.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've attached some chopped down code examples.
It seems ripe for the use of POINTER - but I can't get my head around it!
It seems ripe for the use of POINTER - but I can't get my head around it!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugo - I think you've hit the nail on the head
In the FORTRAN interface file in the DLL I need something like:
pointer(addr_get_darray, new_get_darray)
pointer(addr_put_darray, new_put_darray)
And I can get rid of set_addresses altogether?
(Sure seems to simplify things....)
In the FORTRAN interface file in the DLL I need something like:
pointer(addr_get_darray, new_get_darray)
pointer(addr_put_darray, new_put_darray)
And I can get rid of set_addresses altogether?
(Sure seems to simplify things....)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I assume extern_get_darray is declared in some .h file (or in the header of .c file) as static void* extern_get_darray, right?
The fortran equivalent of C code would be (for "get" function only):
For example:
HTH
Jugoslav
The fortran equivalent of C code would be (for "get" function only):
MODULE Externs INTEGER, PARAMETER:: LPFUNC=4 !Prototype of the callback (from the exe) INTERFACE SUBROUTINE new_get_darray (name_opt, list, item, field, sub, value) CHARACTER*(*) name_opt CHARACTER*(*) list CHARACTER*(*) item CHARACTER*(*) field INTEGER*4 sub REAL*8 value(*) END SUBROUTINE new_get_darray END INTERFACE !Pointer to the external callback procedure POINTER (lpnew_get_darray, new_get_darray) CONTAINS SUBROUTINE set_addresses(addr_get_darray) !Save address of callback lpnew_get_darray; !new_get_darray is now directly callable from !USErs of the module without resorting to !C wrapper INTEGER(LPFUNC):: addr_get_darray lpnew_get_darray = addr_get_darray END SUBROUTINE set_addresses END MODULE Externs
For example:
subroutine somewhere_deep_in_the_code() use Externs ... call new_get_array(...)
HTH
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Looks as if we posted simultaneously; yes, in my sample set_addresses just does the assignment and can be dropped altogether.
Note that you don't necessarily need pointers. You can use standard Fortran's EXTERNAL or INTERFACE on dummy argument routine but only in case that new_get_darray is passed consistently through all arg-lists where they're needed. However, that can be a PITA if call tree is deep and/or wide. Solution with POINTER in a MODULE as above workarounds for the lack of "global routine pointer" in standard Fortran.
Note that you don't necessarily need pointers. You can use standard Fortran's EXTERNAL or INTERFACE on dummy argument routine but only in case that new_get_darray is passed consistently through all arg-lists where they're needed. However, that can be a PITA if call tree is deep and/or wide. Solution with POINTER in a MODULE as above workarounds for the lack of "global routine pointer" in standard Fortran.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Jugoslav...I'll get FORTRAN POINTERS into my head eventually! I have managed to do some significant code simplification using it though. Our old code was peppered with cross language links - basically, pre-POINTER, my predecessors were dancing in and out of C every time a pointer was needed.
Then, if you had to change anything, there were umpteen different places you had to remember to do it. PITA.
It's much better with POINTER.
Then, if you had to change anything, there were umpteen different places you had to remember to do it. PITA.
It's much better with POINTER.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I agree; just bear in mind that this form of POINTER (to a procedure) is non-standard and will work on CVF only.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yeah I know it's non-standard - Steve has warned me about that before. But CVF is the only FORTRAN compiler we use, so as long as Steve and the boys don't decide to get rid of POINTER in merging with Intel, I'll stick with it for convenience! ;o)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If they did get rid of it I'd be at the front of the resulting mob. :) It is rather important for getting things accomplished in the real world.
James
James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You'd have to shove in front of me... :-) Not to worry...

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