How to pass a dynamic structure from vb.net to Fortran DLL

How to pass a dynamic structure from vb.net to Fortran DLL

I am having trouble passing structures or classes from vb.net to my Fortran DLL. In particular I would like to pass a structure or class which dynamic members (i.e. 1D arrays with dynamic memory allocation). I actually can pass fixed-size arrays but not dynamic ones. 

Below is a working example of what I am trying to achieve (the dynamic part is not working). So basically in the vb.net code there is a simple DynStructure that contains an integer and a 1d dynamic integer array. Below is the corresponding fixed-length counterpart (StaStructure). When sub1 is called, the subroutine passes to the DLL (no error) but no access to array members is possible. Under Visual Studio the "dynArr" array is marked as "undefined pointer/array". When sub2 is called everything works well, but the array has a fixed length. 

Thank you in advance for your help!

 

*** VB:NET ***

Imports System.Runtime.InteropServices
Module Intel

    <DllImport("C:\Users\goicochea_j\Documents\03_vb.NET\19_NetPpkg\NetPpkgDll1\PpkgDll\Debug\PpkgDll.dll", CallingConvention:=CallingConvention.StdCall)> _
    Function sub1(ByRef dS As DynStructure) As Double
    End Function

    <DllImport("C:\Users\goicochea_j\Documents\03_vb.NET\19_NetPpkg\NetPpkgDll1\PpkgDll\Debug\PpkgDll.dll", CallingConvention:=CallingConvention.StdCall)> _
    Function sub2(ByRef dS As StaStructure) As Double
    End Function

    <StructLayout(LayoutKind.Sequential)>
    Structure DynStructure
        Dim id As Integer
        Dim dynArr() As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)>
    Structure StaStructure
        Dim id As Integer
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim staArr() As Integer
        Sub New(ByRef n As Integer)
            ReDim staArr(n - 1)
        End Sub
    End Structure

    Sub Main()

        Dim dS As DynStructure
        dS.id = 123
        dS.dynArr = {1, 2, 3}

        ' Call to Fortran DLL
        'sub1(dS)

        Dim sS As StaStructure = New StaStructure(3)
        sS.id = 123
        sS.staArr(0) = 3
        sS.staArr(1) = 2
        sS.staArr(2) = 1

        ' Call to Fortran DLL
        sub2(sS)

    End Sub

End Module

 

*** Fortran ***

module mod_Intel
   
   type DynStructure
      integer              :: id
      integer, allocatable :: dynArr(:)
   end type DynStructure
   
   type StaStructure
      integer              :: id
      integer              :: staArr(3)
   end type StaStructure
   
   contains
   
   subroutine sub1(dS)
      type(DynStructure), intent(inout)   :: dS
      integer                             :: i
      
      !DEC$ ATTRIBUTES DLLEXPORT    :: sub1
      !DEC$ATTRIBUTES STDCALL       :: sub1
      !DEC$ATTRIBUTES ALIAS         : 'sub1' :: sub1
      !DEC$ ATTRIBUTES REFERENCE    :: dS
      
      ! Change id
      dS%id = 321
      
      ! Modify dynamic array
      do i = 1, size(dS%dynArr)
         dS%dynArr(i) = i
      end do
      
   end subroutine sub1
   
   subroutine sub2(sS)
      type(StaStructure), intent(inout)   :: sS
      integer                             :: i
      
      !DEC$ ATTRIBUTES DLLEXPORT    :: sub2
      !DEC$ATTRIBUTES STDCALL       :: sub2
      !DEC$ATTRIBUTES ALIAS         : 'sub2' :: sub2
      !DEC$ ATTRIBUTES REFERENCE    :: sS
      
      ! Change id
      sS%id = 321
      
      ! Modify dynamic array
      do i = 1, size(sS%staArr)
         sS%staArr(i) = i
      end do
      
   end subroutine sub2
   
end module mod_Intel

 

publicaciones de 3 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.

This is an old post - I'm looking to do the same thing, but haven't seen any responses.  Has anyone figured out how to do this?

Imagen de Steve Lionel (Intel)

This is almost certainly not possible without knowing the internals of how VB constructs such structures. You can probably pass individual components, however.

Steve

Inicie sesión para dejar un comentario.