I'm trying to get some FORTRAN code to call a couple c++ functions that I wrote (c_tabs_ being one of them). Linking and everything works just fine, as 开发者_Go百科long as I'm calling functions that don't belong to a class.
My problem is that the functions I want the FORTRAN code to call belong to a class. I looked at the symbol table using nm and the function name is something ugly like this:
00000000 T _ZN9Interface7c_tabs_Ev
FORTRAN won't allow me to call a function by that name, because of the underscore at the beginning, so I'm at a loss.
The symbol for c_tabs when it's not in a class is quite simple, and FORTRAN has no problems with it:
00000030 T c_tabs_
Any suggestions? Thanks in advance.
The name has been mangled, which is what the C++ compiler does to functions to allow things like function overloading and type-safe linkage. Frankly, you are extremely unlikely to be able to call member functions from FORTRAN (because FORTRAN cannot create C++ class instances, among other reasons) - you should express your interface in terms of a C API, which will be callable from just about anywhere.
You will need to create a c-style interface and "extern" it. C++ mangles method names (and overloaded functions) for linking. It's notoriously difficult to link C++ with anything except C++. There are "ways" but I'd highly suggest that you simply export a C interface and use the standard facilities available in Fortran.
If you make the C++ routine have a C-style interface (as described already), then you can use the ISO C Binding feature of Fortran 2003 to call it. With the ISO C Binding, you can specify the name of the routine and (within limits) the C-types and calling conventions (reference, by value) of the arguments and function return. This method works well and has the advantage of being a standard, and therefore compiler and platform dependent, unlike the old methods of calling C from Fortran. The ISO C Binding is supported by many Fortran 95 compilers, such as gfortran >= 4.3.
You have to create extern "C"
wrappers to handle all the details of FORTRAN calling C++, name mangling being the most obvious.
class foo {
public:
int a_method (int x);
}
extern "C" int foo_a (foo * pfoo, int * px) {
if (NULL == pfoo)
return 0;
else
return pfoo->a_method (*px);
}
Notice that FORTRAN compilers pass all arguments by reference, never by value. (Although I'm told this is not strictly speaking part of the FORTRAN standard.)
精彩评论