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

Mixed Language Example

Kipling__Michael
Beginner
635 Views

PREFACE: My solution includes C++ code calling routines from a C dll and a Fortran dll, with calls between the two dll's also.

1st question:
In the example code for using Fortran Modules in C, the variable A in the moduleis accessed with the C code:
extern float EXAMP_mp_A[3];

What is the "mp"? Why is it needed?

2nd question:
Is it necessary in the C code to import each needed variable in the module, or only import the module like this:
__declspec( dllimport ) EXAMP;

Thanks,
Mike

0 Kudos
5 Replies
Steven_L_Intel1
Employee
635 Views
The _mp_ indicates that this is a module symbol - variable A in module EXAMP.

It is necessary to declare each variable separately. C doesn't know anything about Fortran modules.
0 Kudos
Kipling__Michael
Beginner
635 Views
The _mp_ indicates that this is a module symbol - variable A in module EXAMP.

It is necessary to declare each variable separately. C doesn't know anything about Fortran modules.

I have actually tried this, and it takes care of the unresolved external problem I was getting. In the Fortran dll I placed a line like:

!DEC$ ATTRIBUTES DLLEXPORT :: A

At the top of the C code I placed a line similiar to:

__declspec( dllimport ) EXAMP_mp_A;

In a function in the C code which is called by C++ code I set the value of A like this:

EXAMP_mp_A = 123.0;
(note: A is not an array in my code)

This C function then calls a Fortran subroutine from the Fortran dll. The Fortran subroutine uses the module which contains the variable A.

In the debugger in the C routine, I can see that A has been set to 123. However, when I step into the Fortran routine, the value of A = 0.

Mike
0 Kudos
Steven_L_Intel1
Employee
635 Views
I just tried this by modifying the sample C_CALLS_Fortran and it worked fine. Here's what I did.

To project FDLL, I added a file mymod.f90 as follows:

module mymod
real A
!DEC$ ATTRIBUTES DLLEXPORT :: A
end module mymod

I changed fsub.f90 as follows:

SUBROUTINE FSUB (INT_ARG, STR_IN, STR_OUT)
use mymod
IMPLICIT NONE
...
WRITE (INT_STR,'(I5.5)')INT_ARG + INT(A)

In project C_USEDLL I edited cmain.cpp to add these lines:

extern "C" __declspec( dllimport) float MYMOD_mp_A;

void main (int argc, char *argv[])
{
char instring[40];
char outstring[40];
int intarg;

strcpy(instring,"Testing...");
intarg = 123;
MYMOD_mp_A = 5.0;

I made sure that C_USEDLL was the Startup Project (right click on it and select "Set as startup project"), build and run. Stepping into FSUB I could see that A had the value 5 and it was used in the WRITE.
0 Kudos
Kipling__Michael
Beginner
635 Views
Quoting - Mike K

I have actually tried this, and it takes care of the unresolved external problem I was getting. In the Fortran dll I placed a line like:

!DEC$ ATTRIBUTES DLLEXPORT :: A

At the top of the C code I placed a line similiar to:

__declspec( dllimport ) EXAMP_mp_A;

In a function in the C code which is called by C++ code I set the value of A like this:

EXAMP_mp_A = 123.0;
(note: A is not an array in my code)

This C function then calls a Fortran subroutine from the Fortran dll. The Fortran subroutine uses the module which contains the variable A.

In the debugger in the C routine, I can see that A has been set to 123. However, when I step into the Fortran routine, the value of A = 0.

Mike

0 Kudos
Kipling__Michael
Beginner
635 Views

I now have this code working correctly. The 2 things I learned since first asking the question are:

1. It is necessary to export each module variable which will be used by the C routine with something like this:
!DEC$ ATTRIBUTES DLLEXPORT :: A

2. When importing into the C code, include the type of each variable (int, float, double) like:
__declspec(dllimport) double EXAMPL_mp_A;

Thanks,

Mike
0 Kudos
Reply