.Net C# / Fortan interaction problem

.Net C# / Fortan interaction problem

Hi.

I'm writing a .Net application (using VS2005) that need to call a Fortran subroutine to do some heavy computations (2/3D electromagnetic simulations). The Fortran subroutine in turn calls numerous other Fortran and C subroutines. The Fortran part of this project is well tested separately. I build the whole thing as a Dll using Visual Fortran 11.1.051 with just one subroutine as the entry point.

The problems arise when I need to interact between the .Net managed code and the Fortran Dll. I do manage to pass arguments from my C# class to the Fortran Dll, and I do manage to read back the result arrays. This actually works fine.

However there is a problem: I run the Fortran computation as an own thread using System.Thread, because I need my main program to be responsive while the computation runs. Suppose that something happened (error in main program or user interaction, for instance pressing a "Cancel" button) that makes me want to stop the thread. What to do? Just aborting the thread or exiting the calling method does not work, the computation still runs, now as a zombie. I then try to use a stop flag variable which I pass over to Fortran toghether with all the other arguments. If something happens on the .Net side, I set this flag to a certain value. I then check througout the Fortan computation wether this flag is set or not and wether to stop or not.

This does not work. Although I set the variable, it does not get set as seen from the Fortran side. This must be because the variables somehow do not have the same adresses in memory before and after the Fortran call. So what am I missing here?

- Anyone that has a clue to how I can resolve the above situatuon re stopping a thread running a Fortran subroutine?
- What do happen with arguments position in memory when calling a Fortran subroutine from C#? I have tried to pin down certain variables, but that does not seem to help.
- Are there any compiler options/flags I have missed or may be using wrong?

Many thanks in advance for anything that could point me to a solution.

Regards,

O. M. Aakervik
Senior Software Developer
Blueback Reservoir AS
Stavanger, Norway
oma@blueback-reservoir.com

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Some ideas,

1. The Fortran DLL could perform a limited amount of work before returning to the caller, which then calls the DLL to continue more work unless the Cancel button has been pressed.
2. In the calling program, when the Cancel button is pressed, it would need to enter a wait loop until the Fortran routine returns.
When both conditions are satisfied, then the program can exit gracefully.

Regards,

David

I am also writing Fortran code to include in a C# interface. The guys who make the interface had me wrap my Fortran in C++, so it is a C++ DLL. Then they gave me some C++ code for an interupt.

#include "stdio.h"

bool interrupted = false;

// Declaration of the functions available in the fortran dll
extern "C" {

void howMuchDone (int &cpt)
{
printf("%i%% doner", cpt);
}

int ISINTERRUPTED ()
{
if(interrupted)
{
return 1;
}
else
{
return 0;
}
}
}

extern "C" {
__declspec(dllexport) void interrupt ()
{
interrupted = true;
}
}

In my Fotran do loop I have

IF (isinterrupted() .EQ. 1) THEN
ierr = -1 ! modeling was interrupted somehow
RETURN
ENDIF

I have not tested this from C# myself, but I do call the C++ DLL from a Fotran main, and it works. I also had an interface block in there.

INTERFACE
FUNCTION ISINTERRUPTED() ! Interruption from the C++ wrapper
END FUNCTION
END INTERFACE

Hope this helps.

Thank you very much guys. Very useful information. As it often turns out, not many hours after writing this post in desperation, I think I managed to solve the problem. I'm not 100% sure what did it, but I had a(nother) very thourough examination of my code, function calls, compiler options, calling conventions etc. I can now set an integer flag on the managed side that causes the Fortran loop to break. The use of an interrupt function seems more elegant though. At least I can now continue working on my project and maybe come back to refine this issue at a later point.

Again, thank you very much!

Odd Marius

Leave a Comment

Please sign in to add a comment. Not a member? Join today