Fortran Coder

查看: 1015|回复: 14

[混编] FORTRAN与C#中数据传递方式的请教

[复制链接]

58

帖子

9

主题

0

精华

熟手

F 币
254 元
贡献
162 点
发表于 2016-12-12 16:02:05 | 显示全部楼层 |阅读模式
本帖最后由 zhuhuanlai 于 2016-12-12 20:10 编辑

大侠好,小弟有事请赐教!
我有一个成熟的FORTRAN小程序,输入量几十个,输出量几百个。程序的结构为主程序,若干子程序和用MODULE定义的全局变量(程序的输入量,这些变量在主程序和各个子程序中都有用到)。
现想用C#做一个界面,通过FORTRAN输出DLL(初想用显示链接),把用MODULE定义的全局变量(输入量)从C#界面中输入,不知道该如何传递数据。
周老师的书(Intel_Visual_Fortran(周振红))上介绍过三种:
如果使用例程参数,我想传递的是MODULE定义的全局变量,好像不相符。同时好像不能直接用!$DEC导出MODULE
如果使用模块,我看周老师的书中说要把.LIB文件链接到执行文件,不太方便。
如果使用全局变量,感觉有点复杂了。
补充一句,传递数据的同时还会把fortran中需由C#操作的程序用!$DEC导出
小弟是一枚非专业程序猿,提问中不专业的地方,还请谅解!


回复

使用道具 举报

376

帖子

2

主题

0

精华

大宗师

F 币
2585 元
贡献
1549 点

水王勋章元老勋章热心勋章

发表于 2016-12-12 22:25:19 | 显示全部楼层
不妨试试将输入参数转换成namelist,简单易用

58

帖子

9

主题

0

精华

熟手

F 币
254 元
贡献
162 点
 楼主| 发表于 2016-12-13 10:03:23 | 显示全部楼层
pasuka 发表于 2016-12-12 22:25
不妨试试将输入参数转换成namelist,简单易用

感谢您热心的回复,非常感谢!
我在彭国伦的书上了解到NAMELIST类似于COMMOM。通常用于读取文件,很少用在键盘输入,因为用键盘输入会很麻烦。而我的想法是在C#界面中通过键盘输入变量,如果我用NAMELIST,实现起来会不会麻烦一点,同时NAMELIST也可以用!$DEC输出吗?
我主要的想法还是用周振红老师三种方法中选择一种,只是实在是看不明白了。

485

帖子

0

主题

0

精华

宗师

F 币
1070 元
贡献
445 点

规矩勋章元老勋章新人勋章水王勋章

QQ
发表于 2016-12-13 11:03:32 | 显示全部楼层
最简单的方法,还是用参数传递.
可以把输入参数都写在一个 struct 里,传递给 fortran,当做 type 使用.
fortran 里把这个 type 的成员值赋给对应的module中的变量.
(如果有必要,执行完,再把这些值放回type里)
(或者通过另一个输出的 type 返给 C# , C# 显示在界面上)

通过 type / struct 传递,需要注意结构字节对齐.其他的都很方便.我一直都是这么做的.

58

帖子

9

主题

0

精华

熟手

F 币
254 元
贡献
162 点
 楼主| 发表于 2016-12-13 11:48:56 | 显示全部楼层
vvt 发表于 2016-12-13 11:03
最简单的方法,还是用参数传递.
可以把输入参数都写在一个 struct 里,传递给 fortran,当做 type 使用.
fortr ...

感谢您及时且详尽的回复,非常感谢!

感觉您是常用混合编程,我的理解是:
输入量:C#的struct---FORTRAN的type---FORTRAN的module
输出量:FORTRAN的type---C#的struct,再显示在C#界面上
还请指教一下:周振红老师的书上(312页)说由于用到了自派生类型,要把.LIB运行库链接到执行文件,操作起来是不是不太方便,我想用显示链接,有其他的解决办法吗?
另外,您能分享一下这种数据传递的简单例程代码吗,先谢谢了!

58

帖子

9

主题

0

精华

熟手

F 币
254 元
贡献
162 点
 楼主| 发表于 2016-12-13 11:49:12 | 显示全部楼层
vvt 发表于 2016-12-13 11:03
最简单的方法,还是用参数传递.
可以把输入参数都写在一个 struct 里,传递给 fortran,当做 type 使用.
fortr ...

感谢您及时且详尽的回复,非常感谢!

感觉您是常用混合编程,我的理解是:
输入量:C#的struct---FORTRAN的type---FORTRAN的module
输出量:FORTRAN的type---C#的struct,再显示在C#界面上
还请指教一下:周振红老师的书上(312页)说由于用到了自派生类型,要把.LIB运行库链接到执行文件,操作起来是不是不太方便,我想用显示链接,有其他的解决办法吗?
另外,您能分享一下这种数据传递的简单例程代码吗,先谢谢了!

485

帖子

0

主题

0

精华

宗师

F 币
1070 元
贡献
445 点

规矩勋章元老勋章新人勋章水王勋章

QQ
发表于 2016-12-13 12:41:17 | 显示全部楼层
你说的是"显式链接"和"隐式链接"
这与是否使用type和派生类型没有关系的.都可以的.

485

帖子

0

主题

0

精华

宗师

F 币
1070 元
贡献
445 点

规矩勋章元老勋章新人勋章水王勋章

QQ
发表于 2016-12-13 13:01:23 | 显示全部楼层
本帖最后由 vvt 于 2016-12-13 13:02 编辑

我这里有一个和 C++  混编用结构体的例子.可以借鉴
2016-12-13 13-00-54屏幕截图.png


[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;
extern "C" int myfortran( struct in *a , struct out *b);

struct in{
  int i;
  double rr;
};
struct out{
  char a[4];
  double rr;
};
int main()
{
  struct in X;
  struct out Y;
  X.i = 3;
  X.rr= 6.0;    
  int c = myfortran( &X , &Y );
  cout << "C++输出" << Y.a << Y.rr << endl;
  //printf("c=%s,r=%f\n",Y.a,Y.rr);
  return 0;
}

[Fortran] 纯文本查看 复制代码
Integer Function my(pA,pB)  Bind(C,Name="myfortran")
  use , Intrinsic :: ISO_C_Binding
  implicit none
  type T_IN
    integer(C_INT) :: i
    real(C_DOUBLE) :: rr 
  end type T_IN
  type T_OUT
    character(len=4) :: a
    real(C_DOUBLE) :: rr 
  end type T_OUT
  type(T_IN) , pointer :: A
  type(T_OUT), pointer :: B
  type(C_PTR) , value :: pA , pB
  call c_f_pointer( pA , A )
  call c_f_pointer( pB , B )
  write(*,*) '给Fortran输入',A
  B%rr = A%rr + 1.d0
  B%a  = "OUT" // c_null_char
end Function my

58

帖子

9

主题

0

精华

熟手

F 币
254 元
贡献
162 点
 楼主| 发表于 2016-12-13 13:57:06 | 显示全部楼层
本帖最后由 zhuhuanlai 于 2016-12-13 14:01 编辑
vvt 发表于 2016-12-13 13:01
我这里有一个和 C++  混编用结构体的例子.可以借鉴

感谢您的分享!我先消化一下。
您这种混编方式可以不通过DLL输出也能实现,是把两种语言的代码放到一个解决方案的两个工程中,设置启动程序后在运行吧?我用的IVF+VS

485

帖子

0

主题

0

精华

宗师

F 币
1070 元
贡献
445 点

规矩勋章元老勋章新人勋章水王勋章

QQ
发表于 2016-12-13 14:02:53 | 显示全部楼层
通过 obj 或 lib 或 dll 都是可以的,没有多大区别。
VS应该只能用两个工程,不能用同一个工程。(需要把 fortran工程的输出(比如obj或lib)放入C的工程)
也可以用 dll 动态加载方式。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

QQ|捐赠本站|Archiver|关于我们 About Us|QQ群|Fcode

GMT+8, 2017-12-18 14:51

Powered by Discuz! X3.2

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表