简体   繁体   English

使用Fortran调用C ++函数

[英]Using Fortran to call C++ Functions

I'm trying to get some FORTRAN code to call a couple c++ functions that I wrote (c_tabs_ being one of them). 我正在尝试使用一些FORTRAN代码来调用我编写的几个c ++函数(c_tabs_就是其中之一)。 Linking and everything works just fine, as 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. 我的问题是我希望FORTRAN代码调用的函数属于一个类。 I looked at the symbol table using nm and the function name is something ugly like this: 我使用nm查看符号表,函数名称就像这样丑陋:

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. FORTRAN不允许我用这个名字来调用函数,因为开头有下划线,所以我很茫然。

The symbol for c_tabs when it's not in a class is quite simple, and FORTRAN has no problems with it: 当c_tabs不在类中时,它的符号非常简单,FORTRAN没有问题:

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. 这个名称已被破坏,这是C ++编译器所做的功能,允许函数重载和类型安全链接等功能。 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. 坦率地说,你极不可能从FORTRAN调用成员函数(因为FORTRAN不能创建C ++类实例,除其他原因外) - 你应该用C API来表达你的接口,它可以从几乎任何地方调用。

You will need to create a c-style interface and "extern" it. 您将需要创建一个c风格的界面和“extern”它。 C++ mangles method names (and overloaded functions) for linking. C ++破坏了用于链接的方法名称(和重载函数)。 It's notoriously difficult to link C++ with anything except C++. 将C ++与C ++之外的任何东西联系起来都是非常困难的。 There are "ways" but I'd highly suggest that you simply export a C interface and use the standard facilities available in Fortran. 有“方法”,但我强烈建议您只需导出C接口并使用Fortran中提供的标准工具。

You have to create extern "C" wrappers to handle all the details of FORTRAN calling C++, name mangling being the most obvious. 你必须创建extern "C"包装器来处理FORTRAN调用C ++的所有细节,名称修改是最明显的。

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. 请注意,FORTRAN编译器通过引用传递所有参数,而不是通过值传递。 (Although I'm told this is not strictly speaking part of the FORTRAN standard.) (虽然我被告知这不是严格意义上的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. 如果你使C ++例程具有C风格的接口(如已经描述的那样),那么你可以使用Fortran 2003的ISO C Binding功能来调用它。 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. 使用ISO C Binding,您可以指定例程的名称和(在限制范围内)参数和函数返回的C类型和调用约定(引用,按值)。 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. 这种方法运行良好,并且具有标准的优点,因此与编译器和平台相关,不像从Fortran调用C的旧方法。 The ISO C Binding is supported by many Fortran 95 compilers, such as gfortran >= 4.3. 许多Fortran 95编译器支持ISO C绑定,例如gfortran> = 4.3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM