简体   繁体   English

调用C / C ++代码构成visual studio中的fortran程序? (如何在visual studio中编译混合C和fortran代码)

[英]Call C/C++ code form a fortran program in visual studio? (How to compile mixed C and fortran code in visual studio)

i am looking for a way, how i can integrate a c++ code with fortran code (i want simply call some C/C++ functions in the fortran code). 我正在寻找一种方法,如何将c ++代码与fortran代码集成(我只想在fortran代码中调用一些C / C ++函数)。

I have found some proposals for gcc or console compilers, but i have not any idea how to translate this approach to solve integrationproblem within the visual studio. 我已经找到了一些关于gcc或控制台编译器的建议,但我不知道如何翻译这种方法来解决visual studio中的集成问题。

At the time I am thinking about creating a dll form c++ code and calling it from Fortran code. 当时我正在考虑创建一个dll表单c ++代码并从Fortran代码调用它。

Has someone already seen a solution? 有人已经看过解决方案吗? Or what is about overhead for calling function from dll? 或者从dll调用函数的开销是多少? My fortran code transfers a lot of memory into C function, is there any problems, if i would solve this problem with dll? 我的fortran代码将大量内存转移到C函数中,有没有问题,如果我用dll解决这个问题?

thx. 谢谢。

PS I am using Visual Studio 2008 Prof and Intel compilers 10 PS我正在使用Visual Studio 2008教授和英特尔编译器10

PPS I think, i have to specify more concrete, what i want: i want to compile a fortran project in visual studio, which uses some C functions. PPS我想,我必须指定更具体,我想要的东西:我想在visual studio中编译一个fortran项目,它使用一些C函数。

There is a new way to do this that has many advantages -- use the Fortran 2003 ISO C Binding. 有一种新方法可以实现这一点,它具有许多优点 - 使用Fortran 2003 ISO C Binding。 This is a standard and therefore largely OS and language independent way of interfacing Fortran and C (and any language that will use C calling conventions). 这是一个标准,因此主要是操作系统和语言独立的方式来连接Fortran和C(以及任何将使用C调用约定的语言)。 Intel Fortran 11 supports along with numerous other compilers -- not sure about version 10. Using the ISO C Binding, you can match any C name (any case), don't have to worry about underscores (and variations between compilers) and can specify the types and calling methods (by reference, by value) for the arguments. 英特尔Fortran 11支持许多其他编译器 - 不确定版本10.使用ISO C绑定,您可以匹配任何C名称(任何情况),不必担心下划线(和编译器之间的变化)和can为参数指定类型和调用方法(通过引用,按值)。 Intel provides some examples in a folder with their compiler; 英特尔在其编译器的文件夹中提供了一些示例; there are also examples in the gfortran manual and a discussion of additional considerations for Windows. gfortran手册中还有一些示例,并讨论了Windows的其他注意事项。 There are previous questions & answers here and on the Intel Fortran forum. 此处以及英特尔Fortran论坛上有以前的问题和答案。

I integrated C and Fortran about 20 years ago and maintained this integration up to 5 years ago. 我在大约20年前整合了C和Fortran,并在5年前保持了这种集成。 The tricks I used were: 我使用的技巧是:

  • I noticed that the Fortran compiler puts all symbols in uppercase, so make sure your C/C++ functions are written in uppercase as well. 我注意到Fortran编译器将所有符号都放在大写中,因此请确保您的C / C ++函数也以大写形式编写。 To verify how symbols are put in the .OBJ file, use DUMPBIN. 要验证符号在.OBJ文件中的放置方式,请使用DUMPBIN。
  • The Fortran compiler does not understand the name-mangling done by the C++ compiler. Fortran编译器不理解C ++编译器完成的名称修改。 Compile all your C++ functions using the C style convention (using extern "C") 使用C样式约定编译所有C ++函数(使用extern“C”)
  • Arguments in Fortran are always put on the stack using references/pointers. Fortran中的参数总是使用引用/指针放在堆栈中。 Therefore, use pointer-arguments in your C function. 因此,在C函数中使用指针参数。

To be honest, I gave up integrating C and Fortran when I switched to VS2005, so things might have changed since then. 说实话,当我切换到VS2005时,我放弃了集成C和Fortran,所以事情可能会发生变化。 Nevertheless, it's still a good idea to use DUMPBIN to see what kind of symbols the Fortran compiler produces, and adjust the compilation of C/C++ sources to fit with that. 尽管如此,使用DUMPBIN查看Fortran编译器生成的符号类型仍然是一个好主意,并调整C / C ++源代码的编译以适应它。

We do it where I work. 我们在工作的地方做。

Assuming you are using the Intel Fortran compiler, look up its docs. 假设您使用的是英特尔Fortran编译器,请查看其文档。 By default Intel Fortran passes everything by reference and (I believe) uses the C calling convention, with an all caps identifier. 默认情况下,英特尔Fortran通过引用传递所有内容,并且(我相信)使用C调用约定,带有全部大写标识符。 Strings are a particular issue, as Fortran likes to pass the length as a hidden parameter, with a compiler setting for where it goes in the parameter list. 字符串是一个特殊问题,因为Fortran喜欢将长度作为隐藏参数传递,并使用编译器设置将其放在参数列表中。

A wise programer doesn't rely on defaults (where a mistake can lead to undefined behavior), and will use the intel INTERFACE statements to specify calling convention, parameter passing, and the link name for the routine. 明智的程序员不依赖于默认值(错误可能导致未定义的行为),并将使用intel INTERFACE语句指定调用约定,参数传递和例程的链接名称。 The information on this page (ATTRIBUTES Properties and Calling Conventions) is a must-read. 此页面上的信息(属性和呼叫约定)是必读的。 In particular you need it to understand the arcane rules for when and where string length parameters will be passed. 特别是你需要它来理解传递字符串长度参数的时间和位置的神秘规则。 I have a printout of it that I keep on my person. 我有一个打印输出,我保留在我的人身上。 :-) :-)

One other thing to note is that versions of VisualStudio past 6 don't like mixed Fortran and C projects. 另外需要注意的是,过去6年的VisualStudio版本不喜欢混合的Fortran和C项目。 We solved the problem by creating custom project files calling out to makefile, but that's a PITA. 我们通过创建调用makefile的自定义项目文件解决了这个问题,但这是一个PITA。 I'd suggest going with the flow and using separate projects unless you are doing this a lot like we are. 我建议使用流程并使用单独的项目,除非你像我们这样做很多

I was able to build obj from fortran sources thanks to the Custom Build Tools of Visual Express 2010. I guess it is also possible in Visual Studio. 由于Visual Express 2010的自定义构建工具 ,我能够从fortran源构建obj。我想在Visual Studio中也可以。

If you want to mix C and Fortran together, there is a good tutorial here . 如果你想混合C和Fortran在一起,有一个很好的教程在这里 It was written for gcc compilers but you should be able to learn how to deal with name mangling easily. 它是为gcc编译器编写的,但您应该能够轻松地学习如何处理名称修改。

Depending on the compiler, compiled subroutines/functions are Uppercase/lowercase, with a trailing underscore, with a leading underscore,... For a succesfull linkage, you could use dumpbin tools to see how the name appears in the objectfile. 根据编译器的不同,编译的子例程/函数是大写/小写,带有尾随下划线,带有前导下划线,...对于成功的链接,您可以使用dumpbin工具查看名称在对象文件中的显示方式。

An other way is to use iso_c_binding modules, but it is available with Fortran 2003 only. 另一种方法是使用iso_c_binding模块,但它仅适用于Fortran 2003。

Solution found: solution link 解决方案: 解决方案链接

i have had several problem with linking, which could be solved with adding in project properties. 我有几个链接问题,可以通过添加项目属性来解决。

code for testing: 测试代码:

#include <stdio.h>

extern "C"
{
    void f() 
    {
        printf("hi from c\n mega test");
    }
}

fortran code fortran代码

PROGRAM HelloWorld
use, intrinsic :: iso_c_binding
implicit none 
interface
    subroutine f( ) bind( c )
        use, intrinsic :: iso_c_binding
    end subroutine f   
end interface  
call f
END PROGRAM HelloWorld

on demand i can upload the testproject. 按需我可以上传测试项目。 thanks all, hopefully it was my last problem with c and fortran 谢谢大家,希望这是我和c和fortran的最后一个问题

This is the how it works with gcc and console 这就是gcc和console的工作原理

cc: 抄送:

#include <stdio.h>

void f_()
{
    printf("Hi from C\n");
} 

fortran.f90 fortran.f90

PROGRAM HelloWorld
   CALL f
END PROGRAM HelloWorld

Makefile Makefile文件

SRCDIR=.

all: clean release run

release:
    gcc -c c.c -o c.out 
    gfortran -c fortran.f90 -o fortran.out
    gfortran -o out.exe fortran.out c.out
run:
    out.exe

clean:
    @$(ZSHMAGIC)  rm -rf *.exe core* *.o a.out 2> /dev/null

One other question: have i always add '_' after c-function name, which i use in the fortran program? 另外一个问题:我总是在c函数名后添加'_',我在fortran程序中使用了吗?

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

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