立即注册 登录
气象家园 返回首页

清风的个人空间 http://bbs.06climate.com/?1 [收藏] [复制] [分享] [RSS]

日志

fortran和c#混合编程中容易忽视的一点

热度 2已有 2045 次阅读2012-9-9 21:40 |个人分类:c#| fortran, mix, 混合编程

    很久之前就测试过fortran和c#的混编,找了不少参考资料,自以为学的差不多,今天却发现了新的问题。
    很多文献上都会提到,fortran默认是引用传递,c#默认是值传递,在传递多维数组的时候要注意内存行列的优先。结果今天的问题却出在了一维数组上。
假如在fortran中有如下的子例程
SUBROUTINE TEST(Y,M)
!...INTEGER::M
REAL(KIND=4)::Y(M)
PRINT*,Y
RETURN
ENDSUBROUTINE
    例子是给fortran传递一个一维的数组,并且告诉fortran这个数组的长度由于强调了按引用传递,可能就会在c#中写出如下的代码:
[DllImport(DllPath, CallingConvention = CallingConvention.StdCall)]
unsafe public static extern void TEST(ref float[] Y,ref M);
    可是,这样的代码,却是无法运行成功的,运行时会提示,尝试读取或者写入被保护的内存。
    这就是纠结了整整一个下午的问题,不管是去掉ref还是加上ref,还是修改fortran数组的下标,总之,所有该注意的地方几乎都试过了N遍,问题依然存在。
    最后决定找出彭国伦的教材,仔细看了一遍vb中的调用方法,发现是传递了数组的首地址,而这个难道在c#中不是用ref吗?    这时候才突然想起,c#中的数组默认就是按引用传递的,
例如
float[] a=new float[5];
float[] b=a;
实际上b只是指向a的地址,并没有真正复制a的内容
如果是
float b=10;
float a=b;
那么a就是获得了b的内容,而不是地址。
    这样看来,问题还是出在参数的传递上。数组传递的时候不需要ref,基本类型传递的时候才需要指定按地址传递,修改如下:
unsafe public static extern int TEST(float[] Y,ref M);
终于正常了。赶紧记下来,免得下次忘记!

发表评论 评论 (2 个评论)

回复 言深深 2012-9-9 21:58
哈哈,这些才是好东西啊!真心赞···
回复 winter6789 2012-9-10 10:49
真正的经验总结,支持!

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

返回顶部