Fortran与C的混编

\(Fortran\) 作为用于科学计算的一种编译型语言积累了大量数值计算的库,但对于现代编程来说, \(Fortran\) 无 \(GUI\)库 是其一大短板。本文就\(Fortran\) 与 \(C\)混合编程进行简单介绍。

\(Fortran和C\) 混编共有3种方式:

  • 基于源代码的混编
  • 基于动态连接库DLL的混编
  • 基于可执行文件的混编

\(Fortran\) 和 \(C\) 语言同属于编译型语言,因此可以使用任意一种语言来编写主程序或调用程序,对另一种语言编写的例程进行调用。

例程的作用类似于函数,是某个系统对外提供的功能接口或服务的集合,例如操作系统的API服务。


基于源代码的混编

基于源代码的混编是指将 \(C\) 语言文件和 \(Fortran\) 文件放在同一个工程里面直接进行编译链接,生成可执行文件。但是随着\(VC++\)的不断升级,由于一些很重要的库文件升级到高版本 与\(Fortran\) 库文件发生冲突会导致警告和错误,所以这种方式在Windows平台上没那么顺利了。下面例子就 \(Linux\) 平台介绍 \(C\) 和 \(Fortran\) 的混编。

首先来介绍\(Fortran\) 调用 \(C\) ,下面是一段 \(C\) 函数,命名为 \(foo.c\)

 #include <stdio.h>
 void foo()
 {
  printf("foo is called!\n");
 }
 #include <stdlib.h>
 #include <stdio.h>

 extern void c_call_fortran();
 void main()
 {
    c_call_fortran();
 }
!ms$attributes c::c_call_fortran
subroutine c_call_fortran
real*8 x [value]
real*8 y [value]
real*9 z [reference]

write(6,*) 'c_call_fortran is called'
return
end

基于动态连接库DLL的混编

基于动态链接库的混编是指将 \(Fortran\) 或者 \(C\) 语言程序做成动态链接库的形式,供另外一种语言中的主程序调用。

动态连接是把一些经常共用的程序片段做成 \(DLL\) 形式,当执行程序运行时需要调用 \(DLL\) 内的函数时, \(Windows\)系统才将 \(DLL\) 链入内存,然后 \(Windows\) 才在该\(DLL\)中寻找被调用函数,并把它的地址传给调用程序。此时不管程序中有多少的程序调用该 \(DLL\) ,内存中只有一个 \(DLL\) 的副本。

由于 \(Fortran\) 和 \(C\) 在

  • 堆栈管理
  • 目标例程命名
  • 参数传递

所遵循的规则不同,所以要使混合编译获得成功,必须全面一致地协调二者所使用的调用规定。下表是\(Fortran\) 和 \(C\) 所使用的调用约定:

\(Fortran\) \(C/C++\)
缺省约定 \(\underline{} cdecl\)
\(C\) \(\underline{} stdcall\)
\(STDCALL\)

堆栈管理

\(Fortran\) 和 \(C/C++\) 间的例程调用,其参数是通过堆栈来传递的。进栈时,例程参数从左到右依次进入,出栈时例程参数从右至左, 在清理使用完的堆栈时,是由调用程序清理堆栈还是由被调函数清理堆栈,不同的调用约定有不同的规定。

\(Fortran\) \(C/C++\)
主调例程负责清理堆栈 \(C\) \(\underline{} cdecl\)
被调例程负责清理堆栈 缺省约定、\(STDCALL\) \(\underline{} stdcall\)

由于调用约定\(\;C和\; \underline{} cdecl\) 都是主调函数负责清理堆栈,所以在每一处调用点都要插入管理堆栈的代码,使得主调程序的代码稍大一些。因为是主调例程负责清理堆栈,所以主调例程知道有多少

  • 而在 \(Fortran\) 的缺省约定和\( STDCALL\) 约定以及 \(C/C++ 的\underline{} stdcall\) 约定都是被调函数负责清理堆栈,管理堆栈的代码驻留在被调用例程内,且只出现一次。

基于可执行文件的混编

在 \(Windows\) 下程序显式调用 \(dll\) 步骤分为三步

  • \(LoadLibrary\)
  • \(GetProcAdress\)
  • \(FreeLibrary\)

在 \(Qt\) 的\(QLibrary\)类显式调用 \(dll\) 的步骤为

  • \(load\)
  • \(resolve\)
  • \(unload\)

示例代码如下所示:

#include <QtWidgets/QApplication>
#include <QLibrary>

typedef int (*FUN)();
int main(int argc, char * argv)
{
  QApplication a(argc,argv);
  QLibrary mylib("v2.dll");

  if(mylib.load())
  {
    //加载动态连接库成功则开始解析动态连接库里的函数
    FUN test=(FUN)mylib.resolve("FUN");
    if(test)
    {
      //成功连接上test函数
      test(); //调用函数
    }
    else
    {
      //输出未成功连接上test的提示信息
    }
    mylib.unload(); //
  }
  else
  {
     //输出加载动态连接库不成功的信息
  }
}


Fortran与C的混编

时间: 2024-10-12 19:46:16

Fortran与C的混编的相关文章

在vs 2015环境下,c语言和汇编混编操作简析(更新中......)

在VS 2015环境下如何混编. 在新建工程里也会发现了很多问题, 应用程序类型分为:windows应用程序,控制台应用程序,DLL,静态库 静态库: 静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为"库"文件:在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库. 程序编译一般需经预处理.编译.汇编和链接几个步骤.静态库特点是可执行文件中包含了库代码的一份完整拷贝:缺点就是被多次使用就会有多份冗余拷贝. 静态库和动态库是两种共享程序

Python和C|C++的混编(二):利用Cython进行混编

还可以使用Cython来实现混编 1 下载Cython,用python setup.py install进行安装 2 一个实例 ① 创建helloworld目录 创建helloworld.pyx,内容如下: cdef extern from"stdio.h": extern int printf(const char *format, ...) def SayHello(): printf("hello,world\n") ② 编译,最方便的是利用python的Di

Swift和Objective-C混编注意事项

前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋没来讲,的确算是福音,但对于整个iOS编程从业者来讲,真真是,曾几何时"高大上",转瞬之间"矮矬穷".再加上培训班横行,批量批发之下,iOS再也看不到当年的辉煌.iOS10推出后,紧跟着Xcode8也推送了更新,细心者会发现,Xcode8下iOS版本最低适配已变为iOS8.0,加上Swift版本趋于稳定,从某种意义上讲,

swift混编oc碰到的问题

在swift中混编苹果官方的Reachability OC文件. 因为swift工程的target是生成framework而非app,framework中调用oc与app中使用桥接文件还不一样,参考: http://blog.csdn.net/cooldragon/article/details/50172649 主要步骤为: 1.将Reachablity.m 和.h文件加入到工程中 2.在ESPlus.h 中最后加上 (ESPlus为Framework名称) #import <ESPlus/R

在Swift中实现 oc与swift的混编

在Swift中想要引用OC头文件(import),可采用混编的方法,这里以sqlite为例,采用OC-Swift桥的方式实现添加头文件1引入sqlite数据库的库文件 打开工程配置文件,在build Phases选项标签的第三个选项中添加sqlite3 2.先创建桥文件 command + N键选择创建头文件 写一个名字 将要引入的文件在这个Header桥文件里进行引入就行,即将import 语句写在这里 3 配置桥接文件打开工程配置文件,在build setting选项标签搜索框里输入brid

Xcode中C、C++、Object-C3种语言的混编

转自: http://hi.baidu.com/onejw/item/f34390c997cdc226a1b50ae http://www.cocoachina.com/ask/questions/show/57217 http://www.cnblogs.com/uyoug321/archive/2010/12/11/1903499.html Xcode中支持C.C++.Object-C3种语言的混编 Xcode中支持C.C++.Object-C3种语言的混编,那么如果想让编译器混编,只需要将

OC+swift混编

作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/34440159 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢! swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. 先中简单的入手,先研究在同一个工程目录下混合

iOS 静态类库 打包 C,C++文件及和OC混编

iOS 静态类库 编译 C,C++ 我们都知道,OC 原生支持C, 在 创建的 OC类的 .m 里面,可以直接编写C的代码: 同样 Xcode 也支持 OC ,C++的混编,此时,我们通常把OC创建的 .m 文件,手动修改为 .mm 文件以支持 oc c++的混编 基于上面的特性,我们在打包静态类时,可以编译C,OC,C++ 以及三者混合的代码: 因为大多数夸平台的算法库代码都是C或是C++写的,我们利用Xcode编译成静态类库,可以非常安全的提供给别人使用 如下示例: 一:静态库打包 C 代码

OC跟Swift混编

OC项目中使用Swift 本文版权归作者所有,如需转载请联系孟祥月 CSDN博客:http://blog.csdn.net/mengxiangyue  独立博客:http://mengxiangyue.com 最近公司的项目开始计划使用Swift,由于原先的工程都是使用OC编写的,不可能一下全部转换成Swift,所以采用OC与Swift混编的方式是最好的选择.这篇文章只是一个简单的介绍,并没有太高深的知识. 我新建了一个演示的OC工程,当然你可以使用你已经存在的OC的工程.如果我们想要在OC工程