Fortran Coder

查看: 13448|回复: 6
打印 上一主题 下一主题

[混编] C#与fortran混合编程的问题

[复制链接]

58

帖子

9

主题

0

精华

熟手

F 币
256 元
贡献
163 点
跳转到指定楼层
楼主
发表于 2016-11-21 23:30:21 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
大侠好,我用C#调用fortran的DLL文件,对两个项目分别编译,均显示成功。运行C#时出现以下错误,还请抽空帮忙指点,不胜感激!
托管调试助手“PInvokeStackImbalance”在“C:\Users\ZHL\Desktop\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.vshost.exe”中检测到问题。
其他信息: 对 PInvoke 函数“ConsoleApplication1!ConsoleApplication1.Program::Add”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
C#代码如下:
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace ConsoleApplication1
{
    class Program
    {
        [DllImport(@"C:\Users\ZHL\Desktop\ConsoleApplication1\Dll1\Debug\Dll1.dll", EntryPoint = "Add")]     //指定DLL路径,声明外部Add
        extern static int Add(int A,int B);
        static void Main(string[] args)
        {
            int c = Add(1,2);
            Console.WriteLine(c);    //打印c值,正确值为3
            Console.Read();
        }
    }
}

FORTRAN中代码如下:
[Fortran] 纯文本查看 复制代码
subroutine Add(A,B)  Bind(C,Name="Add")
!DEC$ ATTRIBUTES DLLEXPORT :: Add
use , Intrinsic :: ISO_C_Binding
    implicit none
    integer A,B 
    return A+B
    RETURN
  end subroutine

补充说明:我担心是不是fortran区分大小写导致错误,把C#和fortran程序中Add都改为ADD也出现同样的问题,如果需要,我可以把整个文件传上来。
分享到:  微信微信
收藏收藏1 点赞点赞 点踩点踩

58

帖子

9

主题

0

精华

熟手

F 币
256 元
贡献
163 点
沙发
 楼主| 发表于 2016-11-22 21:25:31 | 显示全部楼层
本帖最后由 zhuhuanlai 于 2016-11-22 21:27 编辑
zhuhuanlai 发表于 2016-11-22 21:21
感谢大侠的及时指点,我成功的再现了您的方法,再次感谢!
由于个人水平非常有限,有些尚不明白,还请耐 ...

感谢大侠的及时指点,我成功的再现了您的方法,再次感谢!
由于个人水平非常有限,有些尚不明白,还请耐心指点!
1、        对函数/子程序,我的理解是C#程序须与Bind(C,Name="函数/子程序名称")中的大小写形式保持一致,而FORTRAN程序内其他地方的大小写无所谓。
2、        对变量名称,我的理解是C#程序须与FORTRAN中定义变量语句如integer , value :: A , B中的大小写形式一致,而FORTRAN程序内其他地方的大小写无所谓。
3、        对subroutine和function的,我的理解是子程序和函数类似,唯一不同的是函数可以有返回值,而子程序没有。我见过一些FORTRAN的DLL文件,大都采用subroutine,对这两种的选择有点困惑。我用C#主要做界面,运行时需要从C#中输入几十个数据(可能有数组),需要传入到FORTRAN程序中,在FORTRAN中计算后再把计算结果(包含数据和字符)返回到C#界面,这样的情况应该采用哪种呢?
4、        ISO_C_Binding不会自动更改参数传递约定,还需用value修饰来更改成传值方式?那它的作用除了清理栈道和命名约定外,在其他方面就不再有作用了(比如参数,数组和字符串的传递约定)?
5、        ISO_C_Binding中变量对应关系如图一:


一个fortran整数类型对应的类型如此多,而C#与C的类型还不完全一样如图二所示:

最容易弄混的是就是long,char两个类型,在C/C++中long和int都是4个字节,都对应着C#中的int类型,而C/C++中的char类型占一个字节,用来表示一个ASCII码字符,在C#中能够表示一个字节的是byte类型。与C#中char类型对应的应该是C/C++中的wchar_t类型,对应的是一个2字节的Unicode字符。
如果ISO_C_Binding不会自动更改参数传递约定,那我用C#调用FORTRAN的DLL,是否没有太大的帮助呢?


MC%}{]@X1ILX04A}TNAG{}D.png (31.52 KB, 下载次数: 309)

图一

图一

TBF}HZ9`356~4{FTN$}PHL3.png (16.42 KB, 下载次数: 308)

图二

图二

58

帖子

9

主题

0

精华

熟手

F 币
256 元
贡献
163 点
板凳
 楼主| 发表于 2016-11-23 21:11:35 | 显示全部楼层
fcode 发表于 2016-11-22 21:48
1. 不同的语言(甚至同一个语言的不同编译器),都会对函数名字进行修饰(符号修饰),比如把 Add 变成 _Ad ...

拜谢大侠的指点!
就像黑夜海上航行的导航灯,给我点亮了前进的方向,真心感谢!
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

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

GMT+8, 2024-5-8 04:40

Powered by Tencent X3.4

© 2013-2024 Tencent

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