我正在嘗試從 C# 呼叫 Fortran 代碼。我正在使用 Visual Studio 2019 和英特爾 Fortran 編譯器 (iFort)。
我使用以下代碼創建了一個 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
然后,我使用以下代碼創建了一個 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();
}
}
}
程式一直運行到呼叫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))
我已將“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). Open to any solutions that successfully call Fortran code from a C# project (eventually, a C# project with a WPF GUI, if that matters).
I am in a situation where I can't install Dependency Walker, change environment variables, or pretty much anything that requires elevated privileges.
Any help would be greatly appreciated!
更新:下面@JAlex 的非常徹底和詳細的答案對 .NET Framework 和 .NET Core 都非常有效。我的持續問題是由于我作業場所的用戶帳戶策略阻止運行 *.dll 檔案(顯然)。在正常的、不受限制的系統上嘗試該解決方案作業正常,沒有問題。
uj5u.com熱心網友回復:
首先確保在dllC# 驅動程式二進制檔案旁邊,將 dll 添加到 CSharp 解決方案中。使用 add-existing然后添加為鏈接

然后選擇解決方案中的鏈接并設定為如果更新則復制

這會將 dll 放在輸出檔案夾中

此外,我將 Fortran 中的呼叫約定設定為 CVF,盡管我認為這是可選的,因為我明確指定了哪個引數是REFERENCE,哪個是VALUE。

我檢查了 DLL 匯出使用 dumpbin /exports

以下代碼按縮進方式作業:
Fortran 專案
注意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
夏普專案
請注意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
}
}
Note that the [Out] attribute is required for structure types, but not for primitive types.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/335366.html
標籤:C# 视觉工作室 复式 英特尔-fortran
