By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,920 Members | 1,226 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,920 IT Pros & Developers. It's quick & easy.

C++ and Intel fortran coupling

P: 2
Hi there,

Iím trying to couple Intel FORTRAN and VC++ and after lots of search on books and the other stuff still receiving errors.
The main Problem is passing arrays to Fortran When in FORTRAN I change the arrays value (e.g FA(5)=8) I don't receive any error message bur when I use loop to change array values (e.g., FA(i)=5, I receive following error message.

In programming I'm using MS VS.NET 2003.

Please help me
Thanks

ERRORs:
NTR2CALL error LNK2019: unresolved external symbol _ALI@12 referenced in function _main
NTR2CALL fatal error LNK1120: 1 unresolved externals

================================================== ===FORTRAN
SUBROUTINE ALI(g,b,FA)
Real*8 a,b
integer i
Real*8 FA(10)

b=110+a

DO i = 1, 6
FA(i)=1
enddo

END SUBROUTINE ALI
================================================== ===VC++
// external Fortran function prototype
#include "stdafx.h"
using namespace std;
#include "iostream"
#include "Fortran.h"
extern "C" {void __stdcall ALI(double&,double&,double*);}
#pragma comment(lib, "Lib1.lib")

void main()
{
double a,b;
int i=0;
double FA[10]={1,2,3,4,5,6,7,8,9,10};
cout<<endl
<<"Enter a"
<<endl
<<endl;
cin>>a;
ALI(a,b,FA);

cout<<endl
<<"b=a+110= "
<<b
<<endl
<<endl
<<endl;
for (i=0;i<10;i++)
{
cout<<" "<<FA[i];
}
cout<<endl
<<endl
<<endl;
return;
}
Dec 18 '06 #1
Share this Question
Share on Google+
9 Replies


100+
P: 145
This is something that I'm also very interested in learning. Generally, you'd want to use the very simplest test function you can to learn to do the C++-Fortran linkage.

Would you mind posting your Fortran.h and the relevant .f file.

Also, I suspect that what's happening is that you're passing a copy of the data to your Fortran function, rather than memory addresses or the like. Again, seeing the code might be helpful here.

Best -- Paul
Dec 18 '06 #2

Banfa
Expert Mod 5K+
P: 8,916
As well as seeing the code I would be quite interested in why you would want to link C and Fortran together.
Dec 18 '06 #3

100+
P: 145
As well as seeing the code I would be quite interested in why you would want to link C and Fortran together.
Scientific computing, in particular. Many scientific libraries are written in Fortran (which can still be a bit faster than C++). Performance aside, many in the math/science/engineering community still primarily speak Fortran, making it necessary to get C++ and Fortran to talk to one another.

In fact, I'll be facing the same thing next year. Several of our post-docs wrote a whole bunch of adaptive multiphase flow code in Fortran, and I prefer C++ development. (And so I wrote a whole bunch of object-oriented cancer simulator code in C++.) At some point, either somebody has to give and throw away all their code, or somebody has to bridge the gap. -- Paul
Dec 18 '06 #4

100+
P: 145
Here are some links that may be helpful in tracking down the error:

http://msdn2.microsoft.com/en-us/library/799kze2z.aspx
http://msdn2.microsoft.com/en-us/library/z98k84c3.aspx

The first one looks particularly relevant. See these lines:

# A function was used but the type or number of the parameters did not match the function definition.

# The calling convention (__cdecl, __stdcall, or __fastcall) differs on the use of the function declaration and the function definition.

I wonder if that may be the case here. In particular, if you're running on a 64-bit machine, you may encounter a problem where the C/C++ doubles are larger than the Fortran doubles.

I also see a potential error here:

Expand|Select|Wrap|Line Numbers
  1. SUBROUTINE ALI(g,b,FA)
  2. Real*8 a,b
  3. integer i
  4. Real*8 FA(10)
  5.  
You have "g" in the subroutine declaration, but "a" in the meat of the function. I'm on pre-new at Fortran (I'm so new, I'm not even to "new" status yet.;)), but that doesn't look good to me.

Please do post some feedback soon, so that we can try to resolve these errors. I'm sorry that I didn't see your posted Fortran code. My feeble eyes missed it without the "code" tag. ;) -- Paul
Dec 19 '06 #5

P: 2
Hi Paul,
It is interesting bacause when I'm sending single parametrs it is working properly but about the ayrrays what I receiving is no true.
As I told if you try FA(5)=6 it is working but when I use FA(i) it not working. Would be great if you could share your ideas with me.

Thanks
Farid




Please find the version I checked and with the same problem:
================================================== FORTRAN
SUBROUTINE ALI(a,b,FA)
Real*8 a,b
integer i
Real*8 FA(0:9)


b=110+a
DO i = 1, 6
FA(i)=1
enddo

END SUBROUTINE ALI
================================================== VC++
// external Fortran function prototype

#include "stdafx.h"
using namespace std;
#include "iostream"

extern "C" {void __cdecl ALI(double&,double&,double*);}
#pragma comment(lib, "Lib1.lib")

void main()
{
double a,b;
int i=0;
double FA[10]={1,2,3,4,5,6,7,8,9,10};
cout<<endl
<<"Enter a"
<<endl
<<endl;
cin>>a;
ALI(a,b,FA);

cout<<endl
<<"b=a+110= "
<<b
<<endl
<<endl
<<endl;
for (i=0;i<10;i++)
{
cout<<" "<<FA[i];
}
cout<<endl
<<endl
<<endl;
return;
}
Dec 20 '06 #6

100+
P: 145
Farid,

Good question, and thanks for following up.

In truth, I'll need to do some experimentation to get a better feeling for the problem and solution. (But I'll be using g++/mingw and g95, rather than Intel's fortran compiler and VC++.)

I'm surprised you don't have some sort of "fortran.h" file to help translate variable types and the like. -- Paul

*PS*:
Could you please explain that .lib line in your code? Is that some sort of Fortran<->C++ translation library? I'm somewhat limited in what I can run to directly check your code, given compiler differences, so understanding what differences matter and what differences don't will be helpful. Thanks.
*/PS*

*edit*
Just out of curiosity, have you tried something like
Expand|Select|Wrap|Line Numbers
  1. double* FA;
  2. FA = new double [10];
  3.  
in place of your current FA declaration? It could be something as silly as the C++ to Fortran linking preferring one construct over another. (Although I hope not!) It's worth a try, though.
*/edit*
Dec 21 '06 #7

Banfa
Expert Mod 5K+
P: 8,916
Checking the VC++ documentation for version 6 I think you may have a problem.

My recolection is that C uses a different method to put parameters onto the stack to be passed into a function to other languages, where as I think FORTRAN and PASCAL use a similar format (basically related to the order that the variables are placed on the stack).

In order to pass data between functions written in different languaes these langauges have to have place the function call parameters/be looking for the function call parameters on the stack in the same manor.

This used to be achieve in VC++ using the __pascal and __fortran keywords that declared functions with respectively pascal and fortran calling conventions.

Unfortunately both these keywords are now obsolete.
Dec 21 '06 #8

100+
P: 145
Checking the VC++ documentation for version 6 I think you may have a problem.

My recolection is that C uses a different method to put parameters onto the stack to be passed into a function to other languages, where as I think FORTRAN and PASCAL use a similar format (basically related to the order that the variables are placed on the stack).

In order to pass data between functions written in different languaes these langauges have to have place the function call parameters/be looking for the function call parameters on the stack in the same manor.

This used to be achieve in VC++ using the __pascal and __fortran keywords that declared functions with respectively pascal and fortran calling conventions.

Unfortunately both these keywords are now obsolete.
Hmm, that's an interesting point, and it could go a long way towards explaining why single-parameter functions worked for him but the newest did not. It would also explain the compiler errors on the function declarations not matching their usage.

Here would be a simple test to check that:

Expand|Select|Wrap|Line Numbers
  1. c FORTRAN stuff
  2. SUBROUTINE test(a,b)
  3. Real*8 a,b
  4. a = 0
  5. END SUBROUTINE test
  6.  
Expand|Select|Wrap|Line Numbers
  1. // external Fortran function prototype
  2.  
  3. #include "stdafx.h"
  4. using namespace std;
  5. #include "iostream"
  6.  
  7. extern "C" {void __cdecl test(double&,double&);}
  8.  
  9. // ..
  10.  
  11. double a = 1.0;
  12. double b = 1.0;
  13. test(a,b);
  14. cout << "(a,b): " << a << "," << b << endl;
  15.  
  16. cout << "If the result was 0,1, then fortran accepted the parameters 
  17.          in the expected order." << endl;
  18. cout << "If the result was 1,0, then fortran accepted the parameters 
  19.          in reversed order." << endl;
  20.  
A similar test to try next would be to just pass an array going from 1 to 10, and see if Fortran sees 10 to 1 instead. -- Paul
Dec 21 '06 #9

100+
P: 145
Hmm, that's an interesting point, and it could go a long way towards explaining why single-parameter functions worked for him but the newest did not. It would also explain the compiler errors on the function declarations not matching their usage.

Here would be a simple test to check that:

Expand|Select|Wrap|Line Numbers
  1. c FORTRAN stuff
  2. SUBROUTINE test(a,b)
  3. Real*8 a,b
  4. a = 0
  5. END SUBROUTINE test
  6.  
Expand|Select|Wrap|Line Numbers
  1. // external Fortran function prototype
  2.  
  3. #include "stdafx.h"
  4. using namespace std;
  5. #include "iostream"
  6.  
  7. extern "C" {void __cdecl test(double&,double&);}
  8.  
  9. // ..
  10.  
  11. double a = 1.0;
  12. double b = 1.0;
  13. test(a,b);
  14. cout << "(a,b): " << a << "," << b << endl;
  15.  
  16. cout << "If the result was 0,1, then fortran accepted the parameters 
  17.          in the expected order." << endl;
  18. cout << "If the result was 1,0, then fortran accepted the parameters 
  19.          in reversed order." << endl;
  20.  
A similar test to try next would be to just pass an array going from 1 to 10, and see if Fortran sees 10 to 1 instead. -- Paul
How did things ever turn out for you on this? Steven McDougall told me you found a solution. Thanks -- Paul
Apr 4 '07 #10

Post your reply

Sign in to post your reply or Sign up for a free account.