C#调用Fortran函数返回派生类型时出现NullPointerException
我正在从C程序调用Fortran DLL。我设法将Fortran派生类型作为参数传递,但当调用将派生类型作为返回值返回的函数时,我得到一个NullPointerException 我怀疑我在C#side DLLImport做错了什么 Fortran库:C#调用Fortran函数返回派生类型时出现NullPointerException,c#,fortran,dllimport,fortran-iso-c-binding,C#,Fortran,Dllimport,Fortran Iso C Binding,我正在从C程序调用Fortran DLL。我设法将Fortran派生类型作为参数传递,但当调用将派生类型作为返回值返回的函数时,我得到一个NullPointerException 我怀疑我在C#side DLLImport做错了什么 Fortran库: module FortranCallBack USE ISO_C_BINDING IMPLICIT NONE TYPE, BIND(C) :: FOO INTEGER :: A, B END TYPE CONTAINS SUBROUT
module FortranCallBack
USE ISO_C_BINDING
IMPLICIT NONE
TYPE, BIND(C) :: FOO
INTEGER :: A, B
END TYPE
CONTAINS
SUBROUTINE Test(myFoo) BIND(C)
!DEC$ ATTRIBUTES DLLEXPORT :: Test
TYPE(FOO), INTENT(IN) :: myFoo
write (*,*) "Foo: ", myFoo%A, " ", myFoo%B
END SUBROUTINE
FUNCTION FuncTest() BIND(C) RESULT(RES)
!DEC$ ATTRIBUTES DLLEXPORT :: FuncTest
TYPE(FOO) :: RES
RES = FOO(42, 13)
END FUNCTION
C代码称之为:
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
[StructLayout(LayoutKind.Sequential)]
public class FOO
{
public int a;
public int b;
}
class Program {
static void Main(string[] args)
{
var f = new FOO { a = 1, b = 2 };
// This works
Test(f);
// Here I get NullPointerException...
FOO myFoo = FuncTest();
}
[DllImport("fortran_lib.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl, EntryPoint = "test")]
public static extern void Test( [In] FOO foo );
[DllImport("fortran_lib.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl, EntryPoint = "functest")]
public static extern FOO FuncTest();
}
}
代码是用英特尔Fortran 10.1和.NET framework 4.0编译的结构作为函数结果返回的方式没有很好的标准化,pinvoke marshaller采用了微软的方式。您所能做的就是删除[Marshallas]属性(它肯定不是LPStruct),然后重试。它应该是Test(ref FOO FOO),否则是安全的方法。我尝试删除LPStruct,但在后一个调用中仍然得到相同的空指针异常。始终使用标记,仅在必要时添加版本,以区分您的问题是否特定。例如,您不能使用Fortran 2008,而只能使用Fortran 90。