- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
What if two DLLs contain procedures with the same name. How can I indicate from wich DLL this procedure must be loaded? I'd like to use implicit linking. And what if I'd like to use both procedures in main program, how in this case give them different aliases? Thanks for answers.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Look at a very recent thread where GetProcAddress is used, along with pointers, to get the location of a DLL routine/function. Just save a seperate address for the two procedures after you have obtained them using the code you will find in the thread
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tanks for answers to both.
1. Explicit linking in the same named DLL's procedures
For explicit linking I understood.
DLL1
subroutine ImportedProcedure( number )DLL2
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT, DECORATE, ALIAS: "ImportedProcedure" :: ImportedProcedure
implicit none
integer, intent(in) :: number
print '(1x, a, i)', "From DLL #1: ", number
end subroutine ImportedProcedure
subroutine ImportedProcedure( number )Main Program
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT, DECORATE, ALIAS: "ImportedProcedure" :: ImportedProcedure
implicit none
integer, intent(in) :: number
print '(1x, a, i)', "From DLL #2: ", number
end subroutine ImportedProcedure
program ExplicitLinking
use kernel32
implicit none
print *, "Separately one of them"
call SeparatelyOneOfThem()
print *, "Simultaneously both"
call SimultaneouslyBoth()
read *
contains
subroutine SimultaneouslyBoth
interface
subroutine ImportedProcedure1( number )
!DEC$ ATTRIBUTES STDCALL :: ImportedProcedure1
integer, intent(in) :: number
end subroutine ImportedProcedure1
subroutine ImportedProcedure2( number )
!DEC$ ATTRIBUTES STDCALL :: ImportedProcedure2
integer, intent(in) :: number
end subroutine ImportedProcedure2
end interface
integer Lib1, Lib2, Status
pointer( ptrImportedProcedure1, ImportedProcedure1 )
pointer( ptrImportedProcedure2, ImportedProcedure2 )
Lib1 = LoadLibrary( "DLL1.dll"C )
; Lib2 = LoadLibrary( "DLL2.dll"C )
ptrImportedProcedure1 = GetProcAddress( Lib1, "ImportedProcedure"C )
ptrImportedProcedure2 = GetProcAddress( Lib2, "ImportedProcedure"C )
call ImportedProcedure1( 1 )
call ImportedProcedure2( 2 )
Status = FreeLibrary( Lib1 )
Status = FreeLibrary( Lib2 )
end subroutine SimultaneouslyBoth
subroutine SeparatelyOneOfThem
interface
subroutine ImportedProcedure( number )
!DEC$ ATTRIBUTES STDCALL :: ImportedProcedure
integer, intent(in) :: number
end subroutine ImportedProcedure
end interface
integer Lib1, Lib2, Status
pointer( ptrImportedProcedure, ImportedProcedure )
Lib1 = LoadLibrary( "DLL1.dll"C )
Lib2 = LoadLibrary( "DLL2.dll"C )
ptrImportedProcedure = GetProcAddress( Lib1, "ImportedProcedure"C )
call ImportedProcedure( 1 )
ptrImportedProcedure = GetProcAddress( Lib2, "ImportedProcedure"C )
call ImportedProcedure( 2 )
Status = FreeLibrary( Lib1 )
Status = FreeLibrary( Lib2 )
end subroutine SeparatelyOneOfThem
end program ExplicitLinking
All works:
Separately one of them
From DLL #1: 1
From DLL #2: 2
Simultaneously both
From DLL #1: 1
From DLL #2: 2
2. Source code editing in the same named DLL's procedures
Another way if source code available is to edit them by giving dofferent names to procedures.
2.1. Editing procedures names in sour ce code
DLL1
subroutine ImportedProcedure1( number )
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT, DECORATE, ALIAS: "ImportedProcedure1" :: ImportedProcedure1
implicit none
integer, intent(in) :: number
print '(1x, a, i)', "From DLL #1: ", number
end subroutine ImportedProcedure1
DLL2
subroutine ImportedProcedure2( number )
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT, DECORATE, ALIAS: "ImportedProcedure2" :: ImportedProcedure2
implicit none
integer, intent(in) :: number
print '(1x, a, i)', "From DLL #2: ", number
end subroutine ImportedProcedure2
2.2. Changing only aliases of procedures
DLL1
subroutine ImportedProcedure( number )
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT, DECORATE, ALIAS: "ImportedProcedure1" :: ImportedProcedure
implicit none
integer, intent(in) :: number
print '(1x, a, i)', "From DLL #1: ", number
end subroutine ImportedProcedure
DLL2
subroutine ImportedProcedure( number )
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT, DECORATE, ALIAS: "ImportedProcedure2" :: ImportedProcedure
implicit none
integer, intent(in) :: number
print '(1x, a, i)', "From DLL #2: ", number
end subroutine ImportedProcedure
By applying one of this methods procedures will have different names in DLL. In this case it does not matter wich method of linking, explicit or implicit, are using in next step.
3. Implicit linking in the same named DLL's procedures
Am I understand this case correct? Just modify .lib file by "renaming" ImportedProcedure to ImportedProcedure1 for DLL1 and to ImportedProcedure2 for DLL2. So for source code wich imports DLL's procedures this procedures will have different names. But how do that using LIB.exe? What files are required?LIB in input works with object files (.obj)and COFF files (.lib). Usually with DLL goes .lib (not COFF)and .dll :). Is it possible to do that using only this to files?
Ok. Let I have .obj, .lib and .dll file. To link as I want I should create .def file. But where should Iset calling conventions? Or after .obj it doesn't required: theyalready have been set as specified in ATTRIBUTES (like STDCALL)?
I understand that not so much people need to try something from what I described. May be someone will show me the "way"... And of course I'd like to continue discussion with Jugoslav for this case.
4. Suggestionfor IFC developers
It would be grate to have special attribute like DLLNAME. Just imagine:
interface
subroutine ImportedProcedur e1( number )
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT, DECORATE, ALIAS: "ImportedProcedure", DLLNAME: "DLL1" :: ImportedProcedure1
integer, intent(in) :: number
end subroutine ImportedProcedure1
subroutine ImportedProcedure2( number )
!DEC$ ATTRIBUTES STDCALL, DLLEXPORT, DECORATE, ALIAS: "ImportedProcedure", DLLNAME: "DLL2" :: ImportedProcedure2
integer, intent(in) :: number
end subroutine ImportedProcedure2
end interface
I think it quite possible to realise in compiler. To developers: "Pleeaase".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Am I understand this case correct? Just modify .lib file by "renaming" ImportedProcedure to ImportedProcedure1 for DLL1 and to ImportedProcedure2 for DLL2. So for source code wich imports DLL's procedures this procedures will have different names. But how do that using LIB.exe? What files are required?LIB in input works with object files (.obj)and COFF files (.lib). Usually with DLL goes .lib (not COFF)and .dll :). Is it possible to do that using only this to files?
Ok. Let I have .obj, .lib and .dll file. To link as I want I should create .def file. But where should Iset calling conventions? Or after .obj it doesn't required: theyalready have been set as specified in ATTRIBUTES (like STDCALL)?
I understand that not so much people need to try something from what I described. May be someone will show me the "way"... And of course I'd like to continue discussion with Jugoslav for this case.
This page offers a fairly good explanation. Basically, you don't need to have an .obj file -- (it appears) you can make an import library solely using a .def file with EXPORTS statement, using LIB /DEF:MyDll.def, where you wrote the .def file. Of course, you have to know the name of dll's exports. However, like I said, you have to experiment yourself; I've never done that. If you have troubles, I can give it a try too, but I'm fairly busy these days.Of course, you can set the calling conventions only during compiling/building, and they must match in the caller and the callee; there's no workaround for that. My understanding is that the import library looks roughly like:
SUBROUTINE __imp_WHATEVER()
CALL Function(LOC(DllAddress)+WHATEVEROffset)
END SUBROUTINE
where the two names match by default; however, you can (supposedly) change the first name via LIB+DEF, so that you don't have two __imp_WHATEVER's presented to the linker.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page