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

Common block and struct in a DLL

demo_360
Beginner
1,040 Views
Hello,

Actually I am developing a mixed program With Fortran and C++. The fortran code was in a DLL and the C++ code was a MFC application.

I actually try to bind my common block on struct, but it doesn't work. I want to do this because I have a lot of information to share between the DLL and the MFC application.

Here's what I actually have.

In my main Class(Refra.h)I have some struct Declaration who look like this:

extern "C" struct START{
double XD;
double YD;
double ALPHAD;
float BETAD[2];
float WAVE_HEIGHT;
float CFR;
}START;

extern "C" struct END{
double X_END;
double Y_END;
double ALPHA_END;
double BETA_END[2];
double SHORE_LEN[2];
double SHORE_LOC[2];
double SEA_SIDE[2];
double CFR_END;
double D_HALLER;
bool BEHIND_BW;
}END;


In an other class (RefraDoc.h) I Create some instance of the struct:

struct END m_end;
struct START m_start;

In my fortran DLL I have this common block in my subroutine.

COMMON/START/ XD,YD,ALPHAD,BETAD(2),WAVE_HEIGHT,CFR

COMMON/END/ X_END,Y_END,ALPHA_END,BETA_END(2),SHORE_LEN(2),SHORE_LOC(2),SEA_SIDE(2),CFR_END,D_HALLER,BEHIND_BW


I have try a lot of things to share them but no one works. What is the good way to share my Fortran common block with my C++ Struct?

Thanks in advance for your help.

Demo_360

0 Kudos
10 Replies
Jugoslav_Dujic
Valued Contributor II
1,040 Views
Do you have
!DEC$ATTRIBUTES DLLEXPORT:: START
!DEC$ATTRIBUTES DLLEXPORT:: END

statements in your Fortran code?
0 Kudos
demo_360
Beginner
1,040 Views
Yep #:(

and it doesn't seems to work... Cause I have set some variable of my struct (C++) and I don't have the value in my common block when i call my Fortran subroutine.

I need a kind of bidirectional setting, if i set something in my C++ I want to have it in my Fortran, And if I set in my Fortran code, I want it in my C++.

Demo_360
0 Kudos
demo_360
Beginner
1,040 Views
Here is the answer...

The struct need to be declared like this in you main .h class:

extern "C" _declspec(dllimport) struct START{
double XD;
double YD;
double ALPHAD;
float BETAD[2];
float WAVE_HEIGHT;
float CFR;
}Start;

in your fortran subroutine your Common will look like this and then you DLLEXPORT your common block like this:

COMMON/START/ XD,YD,ALPHAD,BETAD(2),WAVE_HEIGHT,CFR
!DEC$ ATTRIBUTE DLLEXPORT ::START

To use your struct in your MFC application only use the name you gave to yor struct, in this case Start.

Like this you will be able to read and set the value value of the common block from your MFC apps, And you will be able to read and set to the value of the struct from you fortran subroutine...
0 Kudos
ayaz
Beginner
1,040 Views
I am working on a mixed programing project, I am using CVF6.6B and MS VC++ 6.0. In my project the Fortran computation part is in a DLL and I am developing a GUI using MFC. I have the similar stiuation, therefore I followed as descried here to share varibels defined in the common block of Fortran and in a structure at C++ side.
But when I try to set values of my varibles at C++ side, compiler gives error messages, as if those varibels are not defined at atll and are unidentified.

Would someone please explain, how to set the value of varibales, say XD at C++ side?
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,040 Views
You must refer to them as [StructureName].[MemberName], not just as [MemberName]. Thus, for the example above,
you have to use Start.XD = something.

Jugoslav
0 Kudos
ayaz
Beginner
1,040 Views
Hello,

Thank you Jugoslav for the answer. Actually I am still facing the problem of unidentified variable names during compile time. I have a very simple test program, following are my codes:

In Fortran DLL

the file "DAT.FOR" contains variable declarations:


integer PP

integer New

integer Yes

real PI

logical OK1

logical Lgcl
---------

the file "mockfortran.for":


subroutine mockfortran()


implicit none

include 'dat.for'


!DEC$ ATTRIBUTES DLLEXPORT:: mockfortran

COMMON/ START/ PP,New,Yes,PI,OK1,Lgcl

!DEC$ ATTRIBUTE DLLEXPORT:: START


PP = 10

PP= 100*PP


Yes= 42

PI = 3.141

New = Yes* PP

Lgcl = .false.


if (10 .gt. 200) then

OK1 = .true.

else

OK1 = .false.

endif

end subroutine mockfortran
-------

At C++ side, (using MFC)

In "Start.h", contains structure for the common blcok varibales:


extern "C" __declspec(dllimport) struct START {



int PP;
int New;
int Yes;
double PI;
bool OK1;
bool Lgcl;

} Start ;

-------

In "MockDlg.cpp" file:


# include "Start.h"
........

// For calling fortran subroutine, in mockfortran.FOR

extern "C" __declspec(dllimport) void _stdcall mockfortran();
.......

ofstream theOutputFile("output.txt"); // the output text file

mockfortran(); // Fortran subroutine call


theOutputFile << PI << endl ;


theOutputFile << PP << endl ;

theOutputFile << OK1<< endl ;

theOutputFile << Lgcl<< endl ;

------

At the compile time, the error message says the identifiers PI, PP, OK1 and Lgcl are undefined.
What could be the reason?
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,040 Views
Because you need:
theOutputFile << Start.PI << endl ;
theOutputFile << Start.PP << endl ;
theOutputFile  << Start.OK1<< endl ;
theOutputFile  << Start.Lgcl<< endl ;
Jugoslav
0 Kudos
ayaz
Beginner
1,040 Views
Hi

Thanks again for your answer, this has solved the compile time error. But at the link time, the error message says:

MockDlg.obj : error LNK2001: unresolved external symbol __imp__Start

Debug/MockC.exe : fatal error LNK1120: 1 unresolved externals

Error executing xilink6.exe"

Could you please help on this, how to fix this?
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,040 Views
Ah, I overlooked that -- CVF by default exports common (and other names) in uppercase. You should be fine if you replace structure name with START. (Don't forget to link YourDll.lib with C++ host).

Jugoslav
0 Kudos
ayaz
Beginner
1,040 Views
Thank you very much Jugoslav, it worked.
0 Kudos
Reply