我有一个Fortran子 routine ,我从C#调用它,并希望能够终止它.这可以使用我在Fortran routine 运行时在C#中更改的整型变量来完成.但是,将其更改为bool
/logical(c_bool)
不起作用.(在下面的代码中也有一个选项,我可以在其中更改回调函数中的值.)
工作代码(具有int
个参数)
C#:
using System.Runtime.InteropServices;
Console.WriteLine("C# starting");
var cb = new Natives.ActionRefInt(OnUpdateProgress);
var terminate = 0;
var t = Task.Run(() => Natives.TestCallBackAndVariable(cb, ref terminate));
for (int i = 0; i < 4; i++)
{
await Task.Delay(900);
terminate = i * 100;
Console.WriteLine($"C# loop i = {i}, terminate = {terminate}");
}
terminate = -1;
await t;
static void OnUpdateProgress(ref int val2)
{
Console.WriteLine($"C# OnUpdateProgress received val2 = {val2}");
val2 += 10;
Console.WriteLine($"C# OnUpdateProgress setting val2 = {val2}");
}
public static class Natives
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ActionRefInt(ref int progress);
[DllImport(dllName: "FortranLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void TestCallBackAndVariable(
[MarshalAs(UnmanagedType.FunctionPtr)] ActionRefInt callBack,
ref int terminate);
}
Fortran:
subroutine TestCallBackAndVariable(callBack, terminate)
!DEC$ ATTRIBUTES DLLEXPORT::TestCallBackAndVariable
!DEC$ ATTRIBUTES DECORATE,ALIAS:"TestCallBackAndVariable" :: TestCallBackAndVariable
use ISO_C_BINDING
implicit none
! Variables
external :: callBack
integer(C_INT),intent(inout) :: terminate
integer(C_INT) :: ii
integer(C_INT) :: val2
! Body of TestCallBackAndVariable
write(*,*) "Starting TestCallBackAndVariable in fortran lib"
do ii = 1,10
call sleep(1)
val2 = ii
call callBack(val2)
write(*,*) "Fortran loop ii = ",ii,", and terminate = ", terminate, ", and val from callback = ", val2
if (terminate<0) exit
end do
write(*,*) "Finished TestCallBackAndVariable in fortran lib"
end subroutine TestCallBackAndVariable
未按预期代码工作(使用bool
/logical
)
C#:
using System.Runtime.InteropServices;
Console.WriteLine("C# starting");
var cb = new Natives.ActionRefBool(OnUpdateProgress);
var terminate = false;
var t = Task.Run(() => Natives.TestCallBackAndVariable(cb, ref terminate));
for (int i = 0; i < 4; i++)
{
await Task.Delay(900);
Console.WriteLine($"C# loop i = {i}, terminate = {terminate}");
}
terminate = true;
await t;
static void OnUpdateProgress(ref bool val2)
{
Console.WriteLine($"C# OnUpdateProgress received val2 = {val2}");
val2 = true;
Console.WriteLine($"C# OnUpdateProgress setting val2 = {val2}");
}
public static class Natives
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ActionRefBool(ref bool progress);
[DllImport(dllName: "FortranLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void TestCallBackAndVariable(
[MarshalAs(UnmanagedType.FunctionPtr)] ActionRefBool callBack,
ref bool terminate);
}
Fortran:
subroutine TestCallBackAndVariable(callBack, terminate)
!DEC$ ATTRIBUTES DLLEXPORT::TestCallBackAndVariable
!DEC$ ATTRIBUTES DECORATE,ALIAS:"TestCallBackAndVariable" :: TestCallBackAndVariable
use ISO_C_BINDING
implicit none
! Variables
external :: callBack
logical(C_BOOL),intent(inout) :: terminate
integer(C_INT) :: ii
logical(C_BOOL) :: val2
! Body of TestCallBackAndVariable
write(*,*) "Starting TestCallBackAndVariable in fortran lib"
do ii = 1,10
call sleep(1)
val2 = .false.
call callBack(val2)
write(*,*) "Fortran loop ii = ",ii,", and terminate = ", terminate, ", and val from callback = ", val2
if (terminate) exit
end do
write(*,*) "Finished TestCallBackAndVariable in fortran lib"
end subroutine TestCallBackAndVariable
subroutine TestArray(i,j,arr)
在bool/逻辑变量中,c#不修改逻辑terminate
Fortran变量的值.但是,更改OnUpdateProgress
中的逻辑值确实有效.(传播回Fortran)
在这方面的帮助,一如既往地受到高度赞赏.
(VS 2022 Net 6、IFORT 2021.6.0 64位)