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

Explicit / Dynamically loading DLL

bjoern_
Beginner
4,591 Views

Hello,

Im now trying to load a DLL dynamically. I read somethings about it and made a try with the following code

program explicit_dll

implicit none

INTEGER :: hLib, iSt
integer :: intZahl

INTERFACE
SUBROUTINE func(intZahl)
integer :: intZahl
END SUBROUTINE
END INTERFACE
POINTER(lpfnfunc,func)


hLib = LoadLibrary("explicit_dll.dll"C)
lpfnfunc = GetProcAddress(hLib,"func"C)
CALL func(intZahl)
iSt = FreeLibrary(hLib)


end program explicit_dll

butI allways get errors like

This name does not have a type, and must have an explicit type. [FREELIBRARY]

I dont konw where my mistake is

0 Kudos
26 Replies
anthonyrichards
New Contributor III
3,597 Views

Add

USE KERNEL32

to your code

0 Kudos
bjoern_
Beginner
3,597 Views

damn it works thank you!

edit:

now it works, but this brings some other question to my mind.

1. How can I call more than one routine in my code ? Do I have to write this hole code again for another routine or can Ionly and another pointer and do it like this

[...]

pointer(lpfnfunc1,func1)
pointer(lpfnfunc2,func2)

hLib = LoadLibrary("explicit_dll.dll"C)
lpfnfunc1 = GetProcAddress(hLib,"func1"C)
lpfnfucn2 = GetProcAddress(hLib,"fucn2"C)

CALL func1()

call func2()

iSt = FreeLibrary(hLib)

[...]

2. And how do I "call" funcions ? I tried to say something linke valuefunc1 = func1() but it didnt work

0 Kudos
bjoern_
Beginner
3,597 Views

Got it, at least I think so :)

This is what I have done please say if its correct or its bullshit because of stack and things.

program explicit_dll
use kernel32

implicit none

integer :: hLib, status

integer :: intZahl, Zahl

interface

function func3(intZahl)
integer :: intZahl, func3
end function func3

function func4(intZahl)
integer :: intZahl, func4
end function func4

end interface

pointer(pfunc1,func1)
pointer(pfunc2,func2)
pointer(pfunc3,func3)
pointer(pfunc4,func4)

intZahl = 6


hLib = LoadLibrary("Projekt1.dll"C)

pfunc1 = GetProcAddress(hLib,"func1"C)
pfunc2 = GetProcAddress(hLib,"func2"C)
pfunc3 = GetProcAddress(hLib,"func3"C)
pfunc4 = GetProcAddress(hLib,"func4"C)

call func1()
call func2(intZahl)

Zahl = func3(intZahl)
write(*,*)'zahl', Zahl

Zahl = func4(intZahl)
write(*,*)'zahl',Zahl

status = FreeLibrary(hLib)


end program explicit_dll

0 Kudos
Steven_L_Intel1
Employee
3,597 Views
You've got it.
0 Kudos
bjoern_
Beginner
3,597 Views

Okay thinking that I got itlet me think aboutabout loading 2 different dlls in one Fortran main program. So I thought I can do it like I have done it with only one dll. I added anoter two integer variables and in my interface I also added to new routines which are in the second dll. So that the codes looks like this

program laoddll2fach

use kernel32

implicit none

integer :: Zahl,intZahl

interface
subroutine func1()
!output
end subroutine func1

function func3(intZahl)
integer :: intZahl,func3
end function func3

subroutine func12()
!output
end subroutine func12

function func32(intZahl)
integer :: intZahl,func32
end function func32

end interface

pointer(ptrfunc1, func1)
pointer(ptrfunc3, func3)
pointer(ptrfunc12, func12)
pointer(ptrfunc32, func32)

integer :: hLib,hLib2,status, status2

intZahl = 2

hLib = LoadLibrary("Projekt1.dll"C)

ptrfunc1 = GetProcAddress(hLib,"func1"C)
ptrfunc3 = GetProcAddress(hLib,"func3"C)

call func1
Zahl = func3(intZahl)
write(*,*)'zahl func3',Zahl

status = FreeLibrary(hLib)

hLib2 = LoadLibrary("Projekt2.dll"C)

ptrfunc12 = GetProcAddress(hLib2,"func12"C)
ptrfunc32 = GetProcAddress(hLib2,"func32"C)

call func12
Zahl = func32(intZahl)
write(*,*)'zahl func32',Zahl

status2 = FreeLibrary(hLib2)

end program laoddll2fach

But when I try to run it there is an error. An Microsoft Visual C++ Runtime Library error. Which says: This application has requested the Runtime to terminate it in an unsusual way.

I think this has to do with the second dll, because the first two routines are executet correct. So there has to be something worng with my code. But I dont know what?

I thought I got it ...damn :-/

0 Kudos
anthonyrichards
New Contributor III
3,597 Views
Try commenting out the second 'FreeLibrary' function call and see what happens then.
0 Kudos
bjoern_
Beginner
3,597 Views

I think I got it.

I had a mistake in the second dll. But this didnt solve the problem I hat to move the status = FreeLibrary(hLib) to the other FreeLibrary command. So that both of these commands are at the end of the code. And now it works.

0 Kudos
bjoern_
Beginner
3,597 Views

hmm sorry got another stupid question.

Why there is allways a C in the LoadLibrary and GetProcAddress command ?

LoadLibrary(hLib,"dllname.dll" C ) this I mean.

I couldnt notice a difference when I omit the C.

0 Kudos
anthonyrichards
New Contributor III
3,597 Views

Because the function you are calling is a C-function, and itexpects a C-string argument, which is a string of characters terminated by the 'null' character. Typing "a character string"C in your code lets the compiler know that it is to add null character to the end at compilation time. The effectis the same as doing this:

string="a character string"//CHAR(0)

LoadLibrary(hLib, string)

0 Kudos
bjoern_
Beginner
3,597 Views

Okay.

This brings up another question. Is it necessary to use this when I pass Fortran character strings to C/C++ or canI omit it?

edit:

I think I found the answer here

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp

there is wirtten [...]Pointer to a null-terminated string that names the executable module (either a .dll or .exe file).[...]

So I think I have to use it. Or am I wrong ?

0 Kudos
anthonyrichards
New Contributor III
3,597 Views
You are right - null terminate when it is specified to be expected. You may be lucky and get away without the null sometimes, but other times a lack of a null will cause the function to not operate the way you expect.
0 Kudos
bjoern_
Beginner
3,597 Views

Okay I got another thing that interests me.

On this page

http://www.functionx.com/visualc/libraries/explicitdll.htm

I read:

To call a DLL explicitly [...]

When you have finished using the DLL, you can call the FreeLibrary() function.[...]

So I tried what happens when I comment out the iSt = FreeLibrary(hLib) lines in my code. Icouldnt notice a change except for that it worked without an error.

So my question now is, do I have to call FreeLibrary() or can I omit it ?

I ask this because I tried to call two DLLs and used the FreeLibrary() command to end each of the DLL calls some like this

hLib1=LoadLibrary("1.dll"C)

[...]

iSt = FreeLibrary(hLib1)

hLib2=LoadLibrary("2.dll"C)

[...]

iSt=FreeLibrary(hLib2)

Butthis brought me runtime errors. So I moved the first iSt=FreeLibrary(hLib1) to the second one at the end of the code and this worked. But this seems a bit weird to me.

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,597 Views
Which run-time errors? Doesn't smell good to me...

You can defer FreeLibrary until the end or even skip it; it just releases dll's code & frame memory, and it will be automatically released on process exit (even subsequent LoadLibrary do not increase the memory used, just a reference count). However, if I were you, I'd be worried about those errors -- if the dll ain't used anymore, FreeLibrary should be completely harmless.

0 Kudos
bjoern_
Beginner
3,597 Views

I get errors like this

http://img146.imageshack.us/img146/1929/unbenannt0rv.jpg

but these errors only come up when my code looks like this

hLib = LoadLibrary("1.dll"C)

[...]

call func_of_dll_1()

iSt = FreeLibrary(hLib)

hLib2 = LoadLibrary("2.dll"C)

[...]

call func_of_dll_2()

iSt2= FreeLibrary(hLib)

The errors appear after the call of func_of_dll_1() at least I think so. func_of_dll_1() is a console output and right after the output the error appears. But as I said before the code works fine when I move the first FreeLibrary() commandtothe other one. I hope you understand what I want to say :)

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,597 Views
That picture doesn't help much. You should really use the debugger to see where it's failing.
0 Kudos
bjoern_
Beginner
3,597 Views

Does this help ?

Loaded 'C:WINDOWSsystem32MSCTF.dll', no matching symbolic information found.
The thread 0x180 has exited with code 3 (0x3).
The program 'Y:Eigene DateienCompaq Visual Fortran Projektelaoddll2fachDebuglaoddll2fach.exe' has exited with code 3 (0x3).

0 Kudos
Jugoslav_Dujic
Valued Contributor II
3,597 Views
No, not really :-(. I guess one particular statement (READ/WRITE? FreeLibrary?) causes the run-time error. I'm keen to find out which.
0 Kudos
bjoern_
Beginner
3,597 Views

Would it help when I would poste or upload the hole code ?

I mean the code from the Fortan main and the code from the two dlls.

0 Kudos
Intel_C_Intel
Employee
3,597 Views

Hello

try to print status after freing first library before using the next one.

iSt = FreeLibrary(hLib)
print *, iSt

P.S. For compiler code 3 -- internal error and you should go to support and so on, but code 3 for application wich you got-- I do not know what it's mean.

0 Kudos
bjoern_
Beginner
3,381 Views

When I print iSt after the first FreeLibrary I get screenoutput 1 so I think everything is okay, because a fail of FreeLibrary would print 0.

I will try to explain the error a bit more, with acutout of the code.

  1. hLib = LoadLibrary("Projekt1.dll"C)
  2. ptrfunc1 = GetProcAddress(hLib,"func1"C)
  3. call func1
  4. iSt = FreeLibrary(hLib)
  5. write(*,*)'iSt',iSt
  6. hLib2 = LoadLibrary("Projekt2.dll"C)
  7. ptrfunc12 = GetProcAddress(hLib2,"func12"C)
  8. call func12
  9. iSt2 = FreeLibrary(hLib2)

I added some breakpoints at line 5, 6 and 7 and then started debugging. With the run to cursor button I moved to the next breakpoint at line 6. Everything was okay. Screenoutput was iSt 1. And then when I wanted to move from breakpoint at line 6 to then next one at line 7 I got the runtime error with the windows msg box an the error code from I post before.

0 Kudos
Reply