System.TypeLoadException - Can not marshal field...

mozzillo

New member
Joined
May 28, 2003
Messages
1
My problem is about calling a CVF DLL from VB.Net. This dll involves a user defined data type.
I never had problems with Visual Basic 6.0, but I really dont know how to make all this work with VB.NET.

First of all Ive created a very simple dll which should export a user defined type with various data types (a fixed lenght string, a numeric value and an array along with the number of items stored in it.
Code:
!-------------------------------------------------------------
subroutine CVF_VBNET_DLL(myrecord)

  !DEC$ ATTRIBUTES DLLEXPORT::CVF_VBNET_DLL
  !DEC$ ATTRIBUTES ALIAS : "CVF_VBNET_DLL" :: CVF_VBNET_DLL


  ! Variables
 	integer max_npts, i
	parameter(max_npts=100)

 	type t_type
		sequence
		character*(20)		mystring
		double precision	mypar
		double precision	myarray(max_npts)
		integer				npts
	end type t_type

	type(t_type)::myrecord

  ! Body of CVF_VBNET_DLL
  ! I fill up myrecord with some values
  ! I want VB.NET to read the values of this record

  myrecord%mystring="This is mystring"
  myrecord%mypar=123.456
  myrecord%npts=10
  do i=1,myrecord%npts
	myrecord%myarray(i)=i**2
  enddo

end subroutine CVF_VBNET_DLL
!-------------------------------------------------------------

I can easily use this DLL in Visual Basic 6 with the following code in a module

Code:
------------------------------------------------------------
Option Explicit

Public Declare Sub CVF_VBNET_DLL Lib "CVF_VBNET_DLL" (myrecord As t_type)

Public Type t_type
    mystring As String * 20
    myval As Double
    myarray(1 To 100) As Double
    npts As Long
End Type
------------------------------------------------------------

and this code in the form

Code:
------------------------------------------------------------
Option Explicit

Private Sub Command1_Click()
    Dim myrecord As t_type
    
    Call CVF_VBNET_DLL(myrecord)
    
    Here I put my code...
    
End Sub
------------------------------------------------------------

I made some attempts with VB.NET, here is the code I wrote

Code:
------------------------------------------------------------

Public Declare Sub CVF_VBNET_DLL Lib "CVF_VBNET_DLL" (ByRef myrecord As t_type)

Public Structure t_type
    Dim mystring As String
    Dim myval as Double
    Dim myarray() As Double
    Public Sub initialize()
       ReDim myarray(99)
    End Sub
End Structure


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   Dim myrecord As t_type

   myrecord.initialize()
   Call CVF_VBNET_DLL(myrecord)
   
   Here I put my code...

End Sub
    
------------------------------------------------------------

Everything compiles fine, but when I call my DLL I get this error:

"An unhandled exception of type System.TypeLoadException occurred in Project1.exe"
"Additional information: Can not marshal field myarray of type t_type: This type can not be marshaled as a structure field."


Anyone knows whats wrong???
 
Hallo Mozzilo

I have just been having the same problem. I have found a solution but I think there is room for improvement. If you find a better way please let me know. (For example I would like to pass my array as an array)(nigel.findlater@pendragonmedical.com)

Here are some links I found:

http://elitevb.com/content/01,0075,01/05.aspx
http://www.msdnbrasil.com.br/forum/ShowPost.aspx?PostID=13688#13895
ms-help://MS.VSCC/MS.MSDNVS/vbcon/html/vbup1050.htm
http://www.csharphelp.com/archives/archive63.html


Here is my solution:

Imports System.Runtime.InteropServices
...

<StructLayout(LayoutKind.Explicit)> Structure LVCom_Array
<FieldOffset(0)> Dim ua8_0 As Byte
<FieldOffset(1)> Dim ua8_1 As Byte
<FieldOffset(2)> Dim ua8_2 As Byte
<FieldOffset(3)> Dim ua8_3 As Byte
<FieldOffset(4)> Dim ua8_4 As Byte
<FieldOffset(5)> Dim ua8_5 As Byte
<FieldOffset(6)> Dim ua8_6 As Byte
<FieldOffset(7)> Dim ua8_7 As Byte
<FieldOffset(8)> Dim ua8_8 As Byte
<FieldOffset(9)> Dim ua8_9 As Byte
End Structure

Declare Function LVCom_getArrayData Lib "LVCom.dll" Alias "#1" (<MarshalAs(UnmanagedType.Struct)> ByRef Test As LVCom_Array) As Short

...
Dim Test As LVCom_Array
Dim y As Short
Dim i8 As Short

y = LVCom_getArrayData(Test)

MsgBox("Ret: " & y) 0

MsgBox("ua8 0: " & Test.ua8_0) 1
MsgBox("ua8 1: " & Test.ua8_1) 1
 
Back
Top