Fortran Coder

FORTRAN与C#中数据传递方式的请教

查看数: 19404 | 评论数: 14 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2016-12-12 16:02

正文摘要:

本帖最后由 zhuhuanlai 于 2016-12-12 20:10 编辑 大侠好,小弟有事请赐教!我有一个成熟的FORTRAN小程序,输入量几十个,输出量几百个。程序的结构为主程序,若干子程序和用MODULE定义的全局变量(程序的输入量 ...

回复

fcode 发表于 2016-12-25 17:57:07
Y.a ="A"将出现无法将类型“string”隐式转换为“int”的错误
这是 C# 的问题,我无法解决。猜想是因为 Y.a 是 int 类型,不能直接赋予 "A" 的值(因为它是 string 类型)

int c=myfortran(ref X, ref Y);
这里的 c 是一个int变量,赋予它 myfortran 的返回的值。
8楼的代码里并没有明确返回值是多少,如果你想要返回值,可以在 fortran 代码里操作 my
比如 my = 30
返回之后,c 就会等于 30

X 修饰为 ref,是因为结构体一般都比较大,用 ref 传递比较节约空间。并且可以传回。
(传值是无法传回的)
我也不知道你看的那本书为什么说,结构是值类型。感觉很莫名其妙。(当然我对C#并不了解)

整数,浮点数,字符串,数组,都是可以相互传递或返回的。
之所以放到一个结构体里,是因为简单,易于扩展。(比如增加新的成员变量)

本坛的混编分类里有不少帖子,应该也有不少传递数组和字符串的例子,多看看。就学会了。
虽然不一定是 C# 的,但是有相通之处。
zhuhuanlai 发表于 2016-12-24 23:57:29
pasuka 发表于 2016-12-15 10:40
若是成熟Fortran代码,程序的输入文件肯定有规范,C#程序生成一个输入文件,通过dos命令调用Fortran的可 ...

感谢您的热心指导,这几天在消化帖子里的东西,没有及时回复,请谅解,祝您圣诞快乐!!!
pasuka 发表于 2016-12-15 10:40:04
zhuhuanlai 发表于 2016-12-13 10:03
感谢您热心的回复,非常感谢!
我在彭国伦的书上了解到NAMELIST类似于COMMOM。通常用于读取文件,很少用 ...

若是成熟Fortran代码,程序的输入文件肯定有规范,C#程序生成一个输入文件,通过dos命令调用Fortran的可执行程序即可
那么问题就拆解为:C#程序如何生成Fortran的输入文件
namelist只是简化Fortran输入文件读写的一种途径
fcode 发表于 2016-12-13 22:29:51
c# 这样写
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace ConsoleApplication1
{
  class Program
  {
    public struct inx
    {
      public int i;
      public double rr;
    }
    public struct outx
    {
      public int a;
      public double rr;
    }
    [DllImport("fortran_lib")] extern static int myfortran(ref inx A, ref outx B);
    static void Main(string[] args) 
    {
      inx X;
      outx Y;
      X.i = 3;
      X.rr= 6.0;
      Y.a = 1;    
      Y.rr=3.0;
      int c = myfortran( ref X , ref Y );
      Console.WriteLine("c# return:");
      Console.WriteLine(Y.rr);
      Console.Read();
    }
  }
}
vvt 发表于 2016-12-13 14:02:53
通过 obj 或 lib 或 dll 都是可以的,没有多大区别。
VS应该只能用两个工程,不能用同一个工程。(需要把 fortran工程的输出(比如obj或lib)放入C的工程)
也可以用 dll 动态加载方式。
zhuhuanlai 发表于 2016-12-13 13:57:06
本帖最后由 zhuhuanlai 于 2016-12-13 14:01 编辑
vvt 发表于 2016-12-13 13:01
我这里有一个和 C++  混编用结构体的例子.可以借鉴

感谢您的分享!我先消化一下。
您这种混编方式可以不通过DLL输出也能实现,是把两种语言的代码放到一个解决方案的两个工程中,设置启动程序后在运行吧?我用的IVF+VS
vvt 发表于 2016-12-13 13:01:23
本帖最后由 vvt 于 2016-12-13 13:02 编辑

我这里有一个和 C++  混编用结构体的例子.可以借鉴



[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
vvt 发表于 2016-12-13 12:41:17
你说的是"显式链接"和"隐式链接"
这与是否使用type和派生类型没有关系的.都可以的.

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-11-24 01:57

Powered by Tencent X3.4

© 2013-2024 Tencent

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