|
From: scoonce.ulg on 4 Jan 2006 12:59 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 4 Jan 2006 19:42 (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 5 Jan 2006 07:41 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 5 Jan 2006 08:30 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 8 Jan 2006 05:56
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! ] |