From: scoonce.ulg on
I am relatively new to C++ and Fortran, but must be able to call C++
routines from Fortran. From other posts I have learned that the
specific compilers used are important. So:

C++ compiler, option 1:
Microsoft VisualC++ 2005 Express Edition

C++ compiler, option 2:
Microsoft VisualC++ v6.0 (Enterprise Ed.)

FORTRAN compiler:
Visual Fortran Professional Edition 6.0.a (Digital)

I am able to call the following functions shown here. Note that these
functions use _only_ single integers:

C++ function signatures
-----------------------
extern "C" __declspec( dllexport )
int Fact(int n);

extern "C" __declspec( dllexport )
void PythagorasA(float a, float b, float *c);

FORTRAN interface specification
-------------------------------
interface to integer*4 function Fact [C, Alias:'_Fact@4'] (n)
integer*4 n [VALUE]
end


interface to subroutine PythagorasA [STDCALL, Alias:'_PythagorasA(a)12']
(a,b,c)
real*4 a [VALUE]
real*4 b [VALUE]
real*4 c [REFERENCE]
end


The next step, for me, was to try passing an array to C++. Here is the
C++ function signature:

extern "C" __declspec( dllexport )
int FillRandom(float* buf, int len);

and the FORTRAN implementation (ignore the word wrap):

interface
integer function FillRandom(arr, size)
!DEC$ ATTRIBUTES C, ALIAS:'_FillRandom@8', REFERENCE::FillRandom
INTEGER :: size
REAL*4 :: arr(*)
end function FillRandom
end interface

In the fortran, this function is called as:

real*4, POINTER :: arr(:)
integer*4 count
allocate(arr(0:1))
count = FillRandom(arr, 2) ! ==> Access Violation !


I know there are a number of different ways to declare arrays in
Fortran, but I must admit I don't know the implications of these
differences. As to the advice to migrate the Fortran to C++, I would
if I could...

Thanks for any help,
Scott


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bob Hairgrove on
(some comments are embedded in the text...)

On 4 Jan 2006 12:59:49 -0500, scoonce.ulg(a)gmail.com wrote:

>I am relatively new to C++ and Fortran, but must be able to call C++
>routines from Fortran. From other posts I have learned that the
>specific compilers used are important.

Whether or not the specific C++ compiler is important or not, depends
on how the Fortran code expects to call the exported functions, and
whether or not decorated names are exported from the DLL. As you can
see from the extern "C" prefix, the Fortran code need not know that
C++ code is being called because these functions are exported with a C
interface ... i.e., they might just as well have been compiled from
some other language (C, Pascal, assembly, even Visual Basic) as long
as the interface remains callable. But different compilers will
decorate the names differently. However, there are usually ways of
getting a consistent non-decorated name exported from a Windows DLL.
Usually this requires a .DEF file.

>I am able to call the following functions shown here. Note that these
>functions use _only_ single integers:
>
>C++ function signatures
>-----------------------
>extern "C" __declspec( dllexport )
>int Fact(int n);
>
>extern "C" __declspec( dllexport )
>void PythagorasA(float a, float b, float *c);

OK, if this works, that means that the order of passing the arguments
is understood correctly by both the caller and the callee...

>FORTRAN interface specification
>-------------------------------
>interface to integer*4 function Fact [C, Alias:'_Fact@4'] (n)
> integer*4 n [VALUE]
>end

This bit: Alias:'_Fact@4'

wouldn't be necessary if the DLL were compiled with a .DEF file
explicitly naming the exported functions; otherwise, you get decorated
names such as the above.

>interface to subroutine PythagorasA [STDCALL, Alias:'_PythagorasA(a)12']
>(a,b,c)
> real*4 a [VALUE]
> real*4 b [VALUE]
> real*4 c [REFERENCE]
>end
>
>
>The next step, for me, was to try passing an array to C++. Here is the
>C++ function signature:
>
>extern "C" __declspec( dllexport )
>int FillRandom(float* buf, int len);
>
>and the FORTRAN implementation (ignore the word wrap):
>
>interface
> integer function FillRandom(arr, size)
> !DEC$ ATTRIBUTES C, ALIAS:'_FillRandom@8', REFERENCE::FillRandom
> INTEGER :: size
> REAL*4 :: arr(*)
> end function FillRandom
>end interface
>
>In the fortran, this function is called as:
>
>real*4, POINTER :: arr(:)
>integer*4 count
>allocate(arr(0:1))
>count = FillRandom(arr, 2) ! ==> Access Violation !
>
>
>I know there are a number of different ways to declare arrays in
>Fortran, but I must admit I don't know the implications of these
>differences. As to the advice to migrate the Fortran to C++, I would
>if I could...
>
>Thanks for any help,
>Scott

I don't really know anything about Fortran, but I don't see anything
wrong with the C++ side of things. Perhaps a Fortran newsgroup would
be of more help?

--
Bob Hairgrove
NoSpamPlease(a)Home.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Greg Herlihy on
scoonce.ulg(a)gmail.com wrote:
> I am relatively new to C++ and Fortran, but must be able to call C++
> routines from Fortran. From other posts I have learned that the
> specific compilers used are important.
....

Your best bet is probably to search the Web for information about
mixing C++ and Fortran in a single program, since it is unlikely that
you are the first to have had this problem.

A Google search for "Fortran calling C++" turns up some promising
pages:

http://www.physics.utah.edu/~detar/phycs6720/handouts/fortran_binding.html
http://www.neurophys.wisc.edu/comp/docs/notes/not017.html

and many others.

There's even a commercial app that will translate a Fortran program to
C++. In fact I would be half-tempted to write one of my own had I this
assignment.

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Francis Glassborow on
In article <1136371669.847283.34240(a)g47g2000cwa.googlegroups.com>,
scoonce.ulg(a)gmail.com writes
>I know there are a number of different ways to declare arrays in
>Fortran, but I must admit I don't know the implications of these
>differences. As to the advice to migrate the Fortran to C++, I would
>if I could...

If you really need this mixed programming functionality you need a
compatible pair of compilers. Try to find a pair in which the C++
compiler supports extern "Fortran". In general you cannot even mix
object code from different C++ compilers so wishing to mix it between a
Fortran and a C++ compiler is a pretty high requirement.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Pierre Asselin on
scoonce.ulg(a)gmail.com wrote:

> extern "C" __declspec( dllexport )
> int FillRandom(float* buf, int len);

> interface
> integer function FillRandom(arr, size)
> !DEC$ ATTRIBUTES C, ALIAS:'_FillRandom@8', REFERENCE::FillRandom
> INTEGER :: size
> REAL*4 :: arr(*)
> end function FillRandom
> end interface

Your Fortran is passing 'size' by reference. You need to put the
appropriate !DEC$ comment to pass it by value (or change FillRandom()
to take a const int &len).


--
pa at panix dot com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]