简体   繁体   English

在 VS2019 中使用 iFort 从 C# 调用 Fortran

[英]Calling Fortran from C# in VS2019 with iFort

I am trying to call Fortran code from C#.我正在尝试从 C# 调用 Fortran 代码。 I am using Visual Studio 2019 and the Intel Fortran Compiler (iFort).我正在使用 Visual Studio 2019 和英特尔 Fortran 编译器 (iFort)。

I created a fortran DLL project with the following code that compiles without issue (project set to 'release', 'x64'):我使用以下代码创建了一个 fortran DLL 项目,该项目可以正常编译(项目设置为“release”、“x64”):

module Fortran_DLL_Lib
    implicit none
contains
    subroutine adder(a,b,x,y)
        !DEC$ ATTRIBUTES DLLEXPORT, ALIAS:'adder' :: adder
        !DEC$ ATTRIBUTES REFERENCE :: x,y
        implicit none
        integer, intent(in) :: a,b
        integer, intent(out) :: x,y
        y = a + b
        x = 2*a+3*b
    end subroutine
end module

I then created a C# console application with the following code (project also set to 'Release', 'x64'):然后,我使用以下代码创建了一个 C# 控制台应用程序(项目也设置为“Release”、“x64”):

using System;
using System.Runtime.InteropServices;

namespace Call_Fortran_Dll_FromCS_Test
{
    class Program
    {
        [DllImport("Fortran_DLL_Lib.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void adder(int a, int b, [Out] int x, [Out] int y);
        static void Main(string[] args)
        {
            int a = 4;
            int b = 3;
            int x = 0;
            int y = 0;
            Console.WriteLine(a);
            Console.WriteLine(b);
            Console.WriteLine(x);
            Console.WriteLine(y);

            adder(a, b, x, y); //error occurs here
            Console.WriteLine(a);
            Console.WriteLine(b);
            Console.WriteLine(x);
            Console.WriteLine(y);
            Console.ReadKey();
        }
    }
}

The program runs up until the line that calls the fortran function, then returns the error程序一直运行到调用fortran函数的那一行,然后返回错误

Exception thrown: 'System.DllNotFoundException' in Call_Fortran_Dll_FromCS_Test.dll
An unhandled exception of type 'System.DllNotFoundException' occurred in Call_Fortran_Dll_FromCS_Test.dll
Unable to load DLL 'Fortran_DLL_Lib.dll' or one of its dependencies: Access is denied. (0x80070005 (E_ACCESSDENIED))

I have copied both the 'Fortran_DLL_Lib.dll' and 'Fortran_DLL_Lib.lib' files into both the folder that contains the c# project files, as well as the location where the executable project is located, neither seems to help/matter.我已将 'Fortran_DLL_Lib.dll' 和 'Fortran_DLL_Lib.lib' 文件复制到包含 c# 项目文件的文件夹以及可执行项目所在的位置,似乎都无济于事。

This is just based on example code I found trying to find ways to do this and isn't specific to what I'm doing.这只是基于我在尝试寻找方法时发现的示例代码,并不特定于我正在做的事情。 I'm just trying to get a 'proof of concept' together before jumping into more complex applications.在跳入更复杂的应用程序之前,我只是试图将“概念证明”放在一起。 The solution doesn't even necessarily be a DLL, that's just what I saw people recommending as the solution to this (in 7+ year old questions on this site).解决方案甚至不一定是 DLL,这正是我看到人们推荐的解决方案(在本网站上 7 年以上的问题中)。 Open to any solutions that successfully call Fortran code from a C# project (eventually, a C# project with a WPF GUI, if that matters).对从 C# 项目(最终,具有 WPF GUI 的 C# 项目,如果重要的话)成功调用 Fortran 代码的任何解决方案开放。

I am in a situation where I can't install Dependency Walker, change environment variables, or pretty much anything that requires elevated privileges.我处于无法安装 Dependency Walker、更改环境变量或几乎任何需要提升权限的情况。

Any help would be greatly appreciated!任何帮助将不胜感激!

a and b are still reference arguments, unless you add the VALUE attribute in their definition in Fortran. ab仍然是引用参数,除非您在 Fortran 中的定义中添加VALUE属性。

So in C# you need to change your declaration to因此,在 C# 中,您需要将声明更改为

public static extern void adder(ref int a, ref int b, out int x, out int y);

Note that the [Out] attribute is required for structure types, but not for primitive types.请注意,结构类型需要[Out]属性,但基本类型不需要。

Also to make sure the dll is next to the C# driver binary, add the dll into the CSharp solution.还要确保dll位于 C# 驱动程序二进制dll旁边,请将 dll 添加到 CSharp 解决方案中。 Use add-existing and then add as link使用 add-existing然后添加为链接

图2

then select the link in the solution and set to copy if newer然后选择解决方案中的链接并设置为如果更新则复制

图3

this will place the dll in the output folder这会将 dll 放在输出文件夹中

图4

additionally, I set the calling convention in Fortran as CVF, although I think this is optional as I specify explicitly which argument is REFERENCE and which is VALUE .此外,我将 Fortran 中的调用约定设置为 CVF,尽管我认为这是可选的,因为我明确指定了哪个参数是REFERENCE ,哪个是VALUE

图5

I checked the DLL export using dumpbin /exports我使用dumpbin /exports检查了 DLL 导出

图6

The following code works as indented:以下代码按缩进方式工作:

Fortran Project Fortran 项目

Note the addition of the VALUE attributes as well as the REFERENCE ones.请注意VALUE属性和REFERENCE属性的添加。

module mod_Fortran_dll
    use iso_c_binding
    implicit none
contains
    subroutine adder(a,b,x,y)
        !DEC$ ATTRIBUTES DLLEXPORT, alias:'adder' :: adder
        !DEC$ ATTRIBUTES VALUE :: a,b
        !DEC$ ATTRIBUTES REFERENCE :: x,y
        implicit none
        integer, intent(in) :: a,b
        integer, intent(out) :: x,y
        y = a + b
        x = 2*a+3*b
    end subroutine
end module

CSharp Project夏普项目

Note the removal of the CDecl calling convention, and the specific EntryPoint specification.请注意CDecl调用约定和特定EntryPoint规范的删除。

static class Program
{
    #region Fortran
    [DllImport("FortranLib.dll", EntryPoint = "adder")]
    public static extern void adder(int a, int b, [Out] out int x, [Out] out int y);

    #endregion
    static void Main(string[] args)
    {
        int a = 4;
        int b = 3;
        int x = 0;
        int y = 0;

        Console.WriteLine($"a={a}, b={b}, x={x}, y={y}");
        // a = 4, b = 3, x = 0, y = 0

        adder(a, b, out x, out y);

        Console.WriteLine($"a={a}, b={b}, x={x}, y={y}");
        // a = 4, b = 3, x = 17, y = 7
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 vs2019 c# webservice msaccess - vs2019 c# webservice msaccess C# 中的 VS2015 到 VS2019 的 Migration.Net core App - Migration .Net core App from VS2015 to VS2019 in C# 为什么我的文本框随着 C# / VS2019 消失? - Why are my textboxes disappearing with C# / VS2019? 如何在VS2019中为C#设置环境变量 - How to set environment variables for C# in VS2019 VS2019 (16.8.1)、C#、XML 注释、Intellisense 未显示 - VS2019 (16.8.1), C#, XML Comments, Intellisense not showing VS2019 C#,如何解决:没有可用的编辑器 - VS2019 C#, how to fix this: There is no editor available for C# (VS2019):当两者都使用 class 使用 VS 项目结构时,如何将域层与数据层分离 - C# (VS2019): How to separate a domain layer from a data layer when both use a class using VS project structure 如何使用 C# VS2019 更新 TFS 2019 中的查询 - How to update the query in TFS 2019 using C# VS2019 我可以在 C#/VS2019 中找到变量的引用及其映射的引用吗? - Can I find variable's references and its mapping's references in C#/VS2019? 是否还有办法以编程方式在 C#、VS2019 中获取最新版本的 TFVC 存储库? - Is there still a way to programmatically get the latest version of a TFVC repository in C#, VS2019?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM