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

Enable to Call Fortran DLL many times using VB.net

Ahmed_A_2
Beginner
4,590 Views

Hi

 I have created Dll using fortran and I could able to call some subroutines from this Dll file using VB.net and passing the arrays I would like to pass between Fortran Dll and VB.net.But I'm facing a problem to call the subroutine more that one time, in other wards when I run the VB.net(interface) and Run amodel (Which will call the subroutine from Dll file), the simulation will be done without any problems. But if I opened a new model and try to run again I could not call this subroutine again from the Dll (it seems the Dll is busy in some thing, although the simulation is done), so I have to close all the interface to be able to run that model. I hope I could be able to describe my problem, What iam asking for if there is any setting I have to take in consideration while i'm creating the Dll file to over come this problem.

this is the fortran subroutine I'm using

Subroutine FortranDLL(A,IA)
!MS$ATTRIBUTES DLLEXPORT, ALIAS: 'FORTRANDLL' :: FortranDLL 
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION A(5000001),IA(5000001)
OPEN(unit=1000,file=
+'C:\Sams2000\Applications\ATTIF2000\Engine\AttifSavedResults.txt')
CALL ATIFLO00(A,IA)
CLOSE (1000)
Return
End Subroutine FortranDLL

Many thanks

Ahmed

 

0 Kudos
30 Replies
Steven_L_Intel1
Employee
2,959 Views

In the example you show, you are opening (and writing) the same file each time.  Is that really what you want?

What error or behavior do you get that suggests to you that the DLL is "busy"?

I will commnent that a frequent point of confusion in a situation such as this is that some Fortran variables may retain their state across calls to the routine. You need to make sure that all variables are run-time initialized on each entry to the Fortran code.

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

Hi Steve

Thanks a lot for your reply and help. Yes I need to open this file every time I run a model to save some results on it, and I have doubt that might be the source of the problem so I have commented it but the problem still exist. I did not get any error message from the interface(VB.net), but by debauging this is the last position that the interface crash , the interface couldont able to call this subroutine fro the Dll file again. In the same time after I have finished run the model for the first time without problem and the simulation is done, the I cannot replace the Dll file from where it is stored in my computer which give me indication it is still using some where else although the simulation is done.please let me know if there is any thing not clear for you.

Many thanks

Ahmed 

0 Kudos
Steven_L_Intel1
Employee
2,959 Views

Oh, I think I see.  You didn't add STDCALL, REFERENCE to the ATTRIBUTES directive. This results in stack corruption.

Please use:

!DIR$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE, ALIAS: 'FORTRANDLL' :: FortranDLL

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

I have tried what you sent me but unfortunately I have this problem

Unable to find an entry point named 'FORTRANDLL' in DLL 'C:\Sams2000\Applications\ATTIF2000\Engine\ATTIFDLLENG.dll'

and I would like to make sure if  the decleration you sent me is compitibale with powerstation , as I'm using it right now to be able to over write some some routines in the library i'm using.

many thanks

Ahmed

0 Kudos
Steven_L_Intel1
Employee
2,959 Views

If you use !MS$ATTRIBUTES instead of !DIR$ ATTRIBUTES, then it should be compatible. Do you get the error when using Intel Fortran?

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

No I have got this error using  Fortran Power station

and when I did use the decleration as you just tol me as 

Subroutine FortranDLL(A,IA)
!MS$ATTRIBUTES DLLEXPORT, ALIAS: 'FORTRANDLL' :: FortranDLL
!MS$ATTRIBUTES STDCALL:: FortranDLL
!MS$ATTRIBUTES REFERENCE:: FortranDLL
IMPLICIT REAL*8 (A-H,O-Z)
DIMENSION A(5000001),IA(5000001)
OPEN(unit=1000,file=
+'C:\Sams2000\Applications\ATTIF2000\Engine\AttifSavedResults.txt')
CALL ATIFLO00(A,IA)
CLOSE (1000)
Return
End Subroutine FortranDLL

I could be able to create the Dll and call it only once as previously done. So I think this not the souce of the problem

Many thanks

Ahmed

0 Kudos
Steven_L_Intel1
Employee
2,959 Views

For PowerStation, you don't need the STDCALL and REFERENCE directives, but they should not hurt.  Your PowerStation is at least 16 years old, though, so perhaps it has some problems I am not aware of. I suggest using Dependency Walker to see what names the DLL exports.

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

 No problem , So you think if I'm using Intel fortran with this decleration the problem will be solved, and what is the soucre of the proble as you think and dependding on that you sent me a new decleration ?

I do appreciate your continous and respected help

Many thanks

Ahmed

0 Kudos
Steven_L_Intel1
Employee
2,959 Views

The problem is that there are two calling conventions used on 32-bit Windows, C and STDCALL.  VB uses STDCALL and PowerStation defaults to STDCALL.  Intel Fortran defaults to C, and if you don't adjust for this, the stack will be corrupted on each call to the Fortran code. Adding the STDCALL and REFERENCE attributes will make Intel Fortran use STDCALL the same way PowerStation did, and those directives will just reinforce PowerStation's defaults.

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

Ok , if this is the source of the problem in case of intel fortran it should appear  with the  first call(which works fine in my case), not in the second call as in this case, is what i'm thinking in is correct ?

Many thanks

Ahmed

0 Kudos
Steven_L_Intel1
Employee
2,959 Views

No - it would not show up until at least the second call, as the stack corruption occurs when the Fortran routine returns. Depending on what happens in the program, you might not notice a problem until a third or even later call.

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

Many thanks Steve

I will convert to use Intel Fortran right now and I will let you know the status for the program

Really, your hrlp is always important for us

Many thanks

Ahmed

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

Hi Steve

I have used Intel fortran to build the Dll file as you recomended  , but I got anther problem . After the first run has been done (call FortranDLL(A,IA)) without any problem, If I tried to run anther model which mean doing the same call again  (call FortranDLL(A,IA)), the problem cames up as shown in the attached file . It is seems to me that the input file for the engine(DLL), which it will read, becomes busy so in the next call it will not be able to read it/access it . Am I correct , and do you have any suggestion to overcome this problem?. I don't know if the dll subroutine hass been returned why the files it used to read is still busy or used by anther program.

Many thanks

Ahmed 

0 Kudos
Steven_L_Intel1
Employee
2,959 Views

Did you close unit 1 at the end of the first call?  If not, then doing an OPEN on the same unit and file will not reset the position of the file. You could also add a REWIND(1) after the OPEN if that's what you want, but I recommend making sure the unit is closed before the return.

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

Hi Steve

I have closed this unit and now it is working, but still I have a question. If I have stopped the simulation,which means the  FortranDLL(A,IA) has been returned and there should not be any conection between the interface and the DLL file, am I right?. but accually this not the case , if I tried for example to delete or replace the DLL file after the simulation has been stopped I got a message that this file is being used by anther person . In addition if I have statred the same simulation again after stopping it (the same input), the results are different, iam afraid that the diffinations of the arrays inside the engine still the same as the previous simulation and it is not intiallized.I hope I could able to make it clear

Could you please clarfiy that for me.

Many thanks

Ahmed 

0 Kudos
Steven_L_Intel1
Employee
2,959 Views

The DLL is not "returned" - it is still loaded into the address space. The only way for it to be "returned" is for a FreeLibrary call to be made on the library handle - and you can't do that, since it was VB that loaded it and it doesn't give you the handle. So the DLL will remain in use until the VB program exits.

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

Ok, but if during the Dll engine I have defined arrays and common blocks during my calculation .when the engine done the first run and i would like to run a second run does all the declerations for the arrays and common blocks for the new problem will be new decleared or it is still the old arrays for the previous run.

Many Thanks

Ahmed

0 Kudos
Steven_L_Intel1
Employee
2,959 Views

Any static data (COMMON, module variables, etc.) will be unchanged from the last run. You have the responsibility of making sure all variables get reinitialized when you start a new "run". They would only get reset if the DLL was unloaded and reloaded.

0 Kudos
Ahmed_A_2
Beginner
2,959 Views

really I do appreciate your great help all the time. but I still have one more question is ther is any way to unload or reload the dll file without closing the program (Interface) so every thing will be intialized automatically or I have to do that though the code, why question is that our code is too big and there is a room to miss some thing to intialize.

I would like to thank you one more time for your contious help

Ahmed

0 Kudos
Steven_L_Intel1
Employee
2,873 Views

I do not know of a way to do this when VB has loaded the DLL for you. You will need to write code to do the initializations.

0 Kudos
Reply