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

Can't get C++ to FORTRAN example code to work

chris-sn
Beginner
768 Views
I'm trying to create a C++ DLL, which passes data down to a FORTRAN computation engine. It would be possible to pass all the variables down as function arguments but there are uncomfortably many of them. The Intel FORTRAN help topic "Using Modules in Mixed-Language Programming" suggested that a good way would be for the C++ code to directly access module variables.

So a fragment of my FORTRAN is:

module ControlData
...
integer:: c_mIteration
...
end module


and a fragment of my C++ is

extern "C" int ControlData_mp_c_mIteration;
...
ControlData_mp_c_mIteration = 50


I am building the FORTRAN as a static library, and referencing it from my C++ project by including the name of the .lib file as an additional dependency to the C++ project linker.

When I link the C++ project I get
error LNK2001: unresolved external symbol _ControlData_mp_c_mIteration

This is with VS2008 and Intel compiler 11.1

Anybody spot what I am doing wrong? Presumably I am not properly referencing the module name, I have no idea why the _mp_ is there except it was in the example!

And/or I'm having second thoughts about whether having the C++ write its input into FORTRAN module variables is such a good idea.There's anotherhelp topic "Using Common External Data in Mixed-Language Programming", whic suggests I could have the FORTRAN code call back out to the C++ giving it a common block area to fill in. All I really want to do is to pass down a C++ structuer to a fortran subroutine and have it copy the contents into a place of its choosing, what's the most elegant way of doing this?

0 Kudos
1 Solution
Steven_L_Intel1
Employee
768 Views
Since you're not building a DLL, you can ignore the dllexport attribute. Try this instead:

module ControlData
use iso_c_binding

integer(C_INT), bind(C,name='c_mIteration') :: c_mIteration

change the C++ to:

extern "C" int c_mIteration;


No need for the !DEC$ lines. If you want to change the name in C, use exactly the same spelling in the name= specifier in Fortran.

View solution in original post

0 Kudos
5 Replies
Arjen_Markus
Honored Contributor II
768 Views
Yes, you need to export the variables:

!dec$ attributes export :: c_mIteration

Regards,

Arjen
0 Kudos
Steven_L_Intel1
Employee
768 Views
The attribute you want is DLLEXPORT - but keep in mind that, by default, the external name will be _CONTROL_DATA_mp_C_MITERATION. You can change that with an ALIAS attribute (in which case the C name will match what you have in ALIAS) or with a BIND(C, NAME=) attribute on the variable declaration. The _mp_ is there because it is a module entity.

You may want to look at the C interoperability features in the F2003 Standard (link on the forum home page.)
0 Kudos
chris-sn
Beginner
768 Views
Hm, still getting the same error - I now have in the fortran

module ControlData
...

integer:: c_mIteration
!dec$ attributes dllexport :: c_mIteration
!dec$ attributes alias:'c_mIteration' :: ControlData_Iteration

and in the C++

extern "C" int ControlData_Iteration ;

and get

error LNK2001: unresolved external symbol _ControlData_Iteration


Clutching at straws, could it be cos I am building a static library not a dll?

0 Kudos
Steven_L_Intel1
Employee
769 Views
Since you're not building a DLL, you can ignore the dllexport attribute. Try this instead:

module ControlData
use iso_c_binding

integer(C_INT), bind(C,name='c_mIteration') :: c_mIteration

change the C++ to:

extern "C" int c_mIteration;


No need for the !DEC$ lines. If you want to change the name in C, use exactly the same spelling in the name= specifier in Fortran.
0 Kudos
chris-sn
Beginner
768 Views
That works thanks Steve (at least, it is now linking, I've yet to complete and run the rest of the test case)
0 Kudos
Reply