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

Mixed Language Global ?

dajum
Novice
1,164 Views
I have a C++ main program that I am trying to utilize some existing fortran code. I have several common blocks and some initial data in a BLKDATA routine. I wanted to use these commons as globally accessable data from the C++ code. I have compiled the fortran into a .lib file that is linked with my C++ program. I have used
"extern "C" int FDATA" as my definition in the C++ code.
The fortran looks like "common /FDATA/FDATA"

This all links fine. But after going through the initialization, and then coming back to the commons, the
data seems to be "reinitialized". Variables in blkdata are
reset to the value in blkdata, after I had changed them in the code. And values in common blocks go back to zero.

Any Ideas why this doesn't seem to be "Global" data that is not lost? It really looks like local data that is reloaded when the routines are reentered.

Thanks

Dave
0 Kudos
9 Replies
TimP
Honored Contributor III
1,164 Views
Some of the details differ between linux and Windows. There is no standard until f2k. The usual C view of a Fortran labeled COMMON is as a global structure. You would need extern "C" declaration to shut off C++ name mangling of the structure name. Upper vs lower case, appended underscore or not, have different defaults according to the OS.

dumpbin /symbols (Windows)
nm (linux)
will help you see what changes are needed to make the C declaration match in the view of the linker.

On linux, the old f2c program could convert your Fortran COMMON declaration to equivalent C or C++.

I believe examples of the Windows version should come with CVF.
0 Kudos
dajum
Novice
1,164 Views
As I said I don't have any issues with linking. The name mangling and such are NOT a problem. What is a problem for me is how the memory is allocated and filled. It seems to be acting like local instead of global. It gets reset to the initial values between some usages. Any insight into how the common blocks are treated when they are in a .lib file as opposed to a .dll or some other memory management feature I haven't figured out?

Dave
0 Kudos
Steven_L_Intel1
Employee
1,164 Views
You say that you're using a BLOCK DATA subprogram and a static library? Did you add an EXTERNAL reference to the BLOCK DATA from your main program (or some other routine in the library that is always referenced?) If not, the linker won't know to pull in the initialization.

Steve
0 Kudos
dajum
Novice
1,164 Views
Yes I have the blkdata being loaded. The problem is that it seems to be reloaded and I lose values that I have
already modified. And data not in blkdata - but in a common block is also overwritten.

How does it get overwritten? What do I need to do to make sure common blocks are treated as GLOBAL data areas?

Dave
0 Kudos
Steven_L_Intel1
Employee
1,164 Views
You shouldn't have to do anything special. Perhaps you can come up with a small example that demonsrates the problem and attach a ZIP file of it here?

Steve
0 Kudos
dajum
Novice
1,164 Views
I'm trying to put together a sample. My main is a being created in .NET and is using managed code. Does that bring up issues? I didn't create the main, and I'm not
fully up to speed with .NET stuff so it's taking me a while to develop the sample.

Dave
0 Kudos
Steven_L_Intel1
Employee
1,164 Views
How are you "linking" the Fortran code with the managed code? I didn't think that was possible, and that you had to use a DLL or COM.

Steve
0 Kudos
dajum
Novice
1,164 Views
There seem to be a number of ways to get it to link. There is no problem connecting managed and unmanaged C++ code. In general we have a pointer object in a managed C++ class that points to an unmanaged object. That object typically contains function and data members which can be the fortran routines - or at a minimum call or access the fortran routines and data.

I have found via the debugger that the address of my common block seems to be different in two different calls to a fortran function. So why are they different. It appears that the memory is for some reason treated as local storage. But even still - the object that should have been treating it as local never left scope - and I thought it should still be in memory. Maybe that is the problem - the linker doesn't "Know" it is supposed to be global. If I instantiate the object in the main routine - it is available everywhere.

Dave
0 Kudos
Intel_C_Intel
Employee
1,164 Views
What you are trying to do is not easy from managed code. The .NET runtime marshals(copies) data to it's own memory space when it acquires a pointer to an unmanaged structure(your common block). It doesn't let you work with the native pointer, even if you have your code marked as unsafe. It's a real bummer.

My solution to this is a bit complicated:
1. I have created a native COM object that talks to the Fortran DLL. It has two methods:
a. string GetData( string variable_name )
b. bool SetData ( string variable_name, string data )
2. I have created a program that reads the file that contains my common block definition, then spits out C++ header file for the common block structure, and a file that contains (variable_name, offset, type) entries which gets loaded by the DLL created above to do offset lookups into the common block pointer.

The COM interface not only gives me common block access in managed hosts, but in scripting hosts(DHTML) as well.

Jon
0 Kudos
Reply