-
Accessing a static fortran dll from vb.net
I have a structure A, which contains an array of structure B
IE:
struct b
dim x as double
dim y as double
end structure
struct a
dim name as string
dim myb() as b
I need to pass this to a fortran dll.
The error I am getting is field myb. This type cannot be marshalled as a
structure.
-
Re: Accessing a static fortran dll from vb.net
When are you getting the error? And what does the Declare statement look
like?
A few other things to note:
* You have to use the word "Structure" and not "Struct".
* Make sure you define what type of String the Name field is (ANSI or double-byte).
You can do this by using the MarshalAs attribute.
(at the top of the code file
Imports System.Runtime.InteropServices
Structure a
<MarshalAs(UnmanagedType.LPStr)> Dim Name As String 'Ansi string
or
<MarshalAs(UnmanagedType.LPWStr)> Dim Name As String 'double-byte string
-Rob
"John Lott" <lottj@wes.army.mil> wrote:
>
>I have a structure A, which contains an array of structure B
>
>IE:
> struct b
> dim x as double
> dim y as double
> end structure
>
> struct a
> dim name as string
> dim myb() as b
>
>I need to pass this to a fortran dll.
>
>The error I am getting is field myb. This type cannot be marshalled as a
>structure.
>
>
-
Re: Accessing a static fortran dll from vb.net
john,
I have made several posts on this very problem, passing
structures containing areas to unmanaged code. It is
a sample VB that calls a "C" function.
**** VB.NET code
imports System
imports System.Text
imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential)> Public Structure Foo
Public AccessStatus As Integer
Public UserLoginID As Integer
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)> Public Capability()
As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)> Public VoicePath()
As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)> Public Password()
As Byte
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)> Public UserName()
As Byte
Public Sub New(ByVal intUnsage As Integer)
ReDim Capability(127)
ReDim VoicePath(127)
ReDim UserName(19)
ReDim Password(19)
End Sub
End Structure
Public Class Bar
<DllImport("c:\pat\exe\testpassingudt")> Private Shared Function _
TestPassingUDT(ByRef f As Foo) As Integer
End Function
Public Shared Sub Main()
Dim f As Foo = New Foo(0)
Dim status As Integer
Dim strData As String
Dim intPosition As Integer
f.AccessStatus = 10
f.UserLoginID = 255
Encoding.ASCII.GetBytes("Hello world".ToCharArray(), 0, 11, f.UserName,
0)
Encoding.ASCII.GetBytes("My Password".ToCharArray(), 0, 11, f.Password,
0)
f.UserName(15) = 0
status = TestPassingUDT(f)
Console.WriteLine("PS {0:X}", status)
strData = Encoding.ASCII.GetString(f.UserName)
intPosition = strData.IndexOf(Chr(0))
strData = strData.Substring(0, intPosition)
Console.WriteLine("UN ={0}=", strData)
strData = Encoding.ASCII.GetString(f.Password)
intPosition = strData.IndexOf(Chr(0))
strData = strData.Substring(0, intPosition)
Console.WriteLine("PW <{0}>", strData)
strData = Encoding.ASCII.GetString(f.VoicePath)
intPosition = strData.IndexOf(Chr(0))
strData = strData.Substring(0, intPosition)
Console.WriteLine("VP <{0}>", strData)
strData = Encoding.ASCII.GetString(f.Capability)
intPosition = strData.IndexOf(Chr(0))
strData = strData.Substring(0, intPosition)
Console.WriteLine("CP <{0}>", strData)
Console.WriteLine("AS {0:X}", f.AccessStatus)
Console.WriteLine("UL {0:X}", f.UserLoginID)
End Sub
End Class
**** C++ code
#include <windows.h>
#include <stdio.h>
typedef struct
{
int AccessStatus;
int UserLoginID;
BYTE abytCapability [ 128 ];
BYTE abytVoicePath [ 128 ];
BYTE abytPassword [ 20 ];
BYTE abytUserName [ 20 ];
} TypeTestPassingUDT;
extern "C" DWORD __stdcall TestPassingUDT
(TypeTestPassingUDT * pUserData)
{
char szTemp [ 128 ];
memcpy (szTemp,
(char *) pUserData->abytUserName,
16);
szTemp [ 16 ] = 0;
printf ("DLL US <%s>\n",szTemp);
sprintf ((char *) pUserData->abytUserName,
"<HI-%s>",
szTemp);
strcpy ((char *) pUserData->abytVoicePath,
"J:VoicePath");
strcpy ((char *) pUserData->abytCapability,
"This is the capability");
pUserData->AccessStatus = 0x12345678;
pUserData->UserLoginID = 0xFEDCBA98;
return 0xAABBCCDD;
} // TestPassingUDT ()
**** C linker DEF file
LIBRARY TestPassingUDT
EXPORTS
TestPassingUDT @1
"John Lott" <lottj@wes.army.mil> wrote:
>
>I have a structure A, which contains an array of structure B
>
>IE:
> struct b
> dim x as double
> dim y as double
> end structure
>
> struct a
> dim name as string
> dim myb() as b
>
>I need to pass this to a fortran dll.
>
>The error I am getting is field myb. This type cannot be marshalled as a
>structure.
>
>
-
Re: Accessing a static fortran dll from vb.net
"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
I am using "structure" it was just a typo on the posting
the declare is as follows
friend declare sub engmod lib "WesEngMod" (<Marshalas(unmanagedtype.struct)>
byref ac as aircraftdata
StructLayout(LayoutKind.Sequential)> Friend Structure typeTireData
Dim x As Double
Dim y As Double
Dim Press As Double
Dim CAREA As Double
Dim PHIE As Double
Dim PCTGW As Double
Dim USE_STRS As Short
Dim USE_ESWL As Short
Dim USE_ACN As Short
Dim USE_PCR As Short
Dim USE_LED As Short
Dim spacer1 As Short
Dim spacer2 As Short
Dim spacer3 As Short
End Structure
<StructLayout(LayoutKind.Sequential)> Friend Structure typeaircraftdata
<MarshalAs(UnmanagedType.LPStr)> Public acName As String
Public tires() As typeTireData
Dim STDLOAD As Double
Dim MAXLOAD As Double
Dim MINLOAD As Double
Dim PCTM As Double
Dim Passes As Double
Dim GW As Double ' Load
<MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> Public xEval()
As Double
<MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> Public yEval()
As Double
Dim NEVAL As Short
Dim NTIRES As Short
Dim Type As Short
Dim spacer2 As Short
Public Sub initialize(ByVal vehiclename As String)
acName = vehiclename & New String(" ", 120 - vehiclename.Length)
ReDim tires(99)
ReDim xEval(99)
ReDim yEval(99)
End Sub
End Structure
The error occurs as soon as I attemp to call the function. It says system.typeloadexception.
Additional information cannot marshal field tires of typeaircraftdata.This
type cannot be marshalled as a structure field.
>
>
>When are you getting the error? And what does the Declare statement look
>like?
>
>A few other things to note:
>
>* You have to use the word "Structure" and not "Struct".
>
>* Make sure you define what type of String the Name field is (ANSI or double-byte).
>You can do this by using the MarshalAs attribute.
>
>(at the top of the code file
>Imports System.Runtime.InteropServices
>
>Structure a
> <MarshalAs(UnmanagedType.LPStr)> Dim Name As String 'Ansi string
>
>or
>
> <MarshalAs(UnmanagedType.LPWStr)> Dim Name As String 'double-byte string
>
>-Rob
>
>
>"John Lott" <lottj@wes.army.mil> wrote:
>>
>>I have a structure A, which contains an array of structure B
>>
>>IE:
>> struct b
>> dim x as double
>> dim y as double
>> end structure
>>
>> struct a
>> dim name as string
>> dim myb() as b
>>
>>I need to pass this to a fortran dll.
>>
>>The error I am getting is field myb. This type cannot be marshalled as
a
>>structure.
>>
>>
>
-
Re: Accessing a static fortran dll from vb.net
John,
I have never had the pleasure of passing a neested structure. However,
there is a error in your defintion of typeaircraftdata. You didn't
marshall typeTireData in the structure typeaircraftdata. Arrays need to
be marshalled when passed to unmanaged code.
<MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> _
Public tires () as typeTireData
I don't have my reference material here so I don't recall whether
the sizeconst:= is in bytes or typeTireData size.
You will also need to be careful with the acname string.
As a pilot, this looks like an interesting application
Pat
"John Lott" <lottj@wes.army.mil> wrote:
>
>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>
>I am using "structure" it was just a typo on the posting
>
>the declare is as follows
>
>friend declare sub engmod lib "WesEngMod" (<Marshalas(unmanagedtype.struct)>
>byref ac as aircraftdata
>
>StructLayout(LayoutKind.Sequential)> Friend Structure typeTireData
> Dim x As Double
> Dim y As Double
> Dim Press As Double
> Dim CAREA As Double
> Dim PHIE As Double
> Dim PCTGW As Double
> Dim USE_STRS As Short
> Dim USE_ESWL As Short
> Dim USE_ACN As Short
> Dim USE_PCR As Short
> Dim USE_LED As Short
> Dim spacer1 As Short
> Dim spacer2 As Short
> Dim spacer3 As Short
> End Structure
>
> <StructLayout(LayoutKind.Sequential)> Friend Structure typeaircraftdata
> <MarshalAs(UnmanagedType.LPStr)> Public acName As String
> Public tires() As typeTireData
> Dim STDLOAD As Double
> Dim MAXLOAD As Double
> Dim MINLOAD As Double
> Dim PCTM As Double
> Dim Passes As Double
> Dim GW As Double ' Load
> <MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> Public xEval()
>As Double
> <MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> Public yEval()
>As Double
> Dim NEVAL As Short
> Dim NTIRES As Short
> Dim Type As Short
> Dim spacer2 As Short
>
> Public Sub initialize(ByVal vehiclename As String)
>
> acName = vehiclename & New String(" ", 120 - vehiclename.Length)
> ReDim tires(99)
> ReDim xEval(99)
> ReDim yEval(99)
> End Sub
> End Structure
>
>The error occurs as soon as I attemp to call the function. It says system.typeloadexception.
>Additional information cannot marshal field tires of typeaircraftdata.This
>type cannot be marshalled as a structure field.
>>
>>
>>When are you getting the error? And what does the Declare statement look
>>like?
>>
>>A few other things to note:
>>
>>* You have to use the word "Structure" and not "Struct".
>>
>>* Make sure you define what type of String the Name field is (ANSI or double-byte).
>>You can do this by using the MarshalAs attribute.
>>
>>(at the top of the code file
>>Imports System.Runtime.InteropServices
>>
>>Structure a
>> <MarshalAs(UnmanagedType.LPStr)> Dim Name As String 'Ansi string
>>
>>or
>>
>> <MarshalAs(UnmanagedType.LPWStr)> Dim Name As String 'double-byte string
>>
>>-Rob
>>
>>
>>"John Lott" <lottj@wes.army.mil> wrote:
>>>
>>>I have a structure A, which contains an array of structure B
>>>
>>>IE:
>>> struct b
>>> dim x as double
>>> dim y as double
>>> end structure
>>>
>>> struct a
>>> dim name as string
>>> dim myb() as b
>>>
>>>I need to pass this to a fortran dll.
>>>
>>>The error I am getting is field myb. This type cannot be marshalled as
>a
>>>structure.
>>>
>>>
>>
>
-
Re: Accessing a static fortran dll from vb.net
I found an intermediate solution
I converted the structures to classes and added a funtion called write
which returns a byte array.
public function write() as byte()
dim x as new system.io.memorystream
dim y as new system.io.binarywriter(y)
' write data one variable at a time
y.write(xcoordinate)
y.write(ycoordinate)
' etc etc
return x.getbuffer()
end function
In the main code
dim intptr as system.intptr
' 8176 is the size of the array
intptr = marshal.allochglobal(8176)
marshal.copy(myclass.write(),0,intptr,8176)
myanswer = engmod(intptr)
declare function engmod lib "WesEngMod" (byval intptr as system.intptr)
as double
I am sure there is a better way but I have not been able to find it
"Patrick Ireland" <ireland@airmail.net> wrote:
>
>John,
>
>I have never had the pleasure of passing a neested structure. However,
>there is a error in your defintion of typeaircraftdata. You didn't
>marshall typeTireData in the structure typeaircraftdata. Arrays need to
>be marshalled when passed to unmanaged code.
>
> <MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> _
> Public tires () as typeTireData
>
>I don't have my reference material here so I don't recall whether
>the sizeconst:= is in bytes or typeTireData size.
>
>You will also need to be careful with the acname string.
>
>As a pilot, this looks like an interesting application
>
>Pat
>
>"John Lott" <lottj@wes.army.mil> wrote:
>>
>>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>>
>>I am using "structure" it was just a typo on the posting
>>
>>the declare is as follows
>>
>>friend declare sub engmod lib "WesEngMod" (<Marshalas(unmanagedtype.struct)>
>>byref ac as aircraftdata
>>
>>StructLayout(LayoutKind.Sequential)> Friend Structure typeTireData
>> Dim x As Double
>> Dim y As Double
>> Dim Press As Double
>> Dim CAREA As Double
>> Dim PHIE As Double
>> Dim PCTGW As Double
>> Dim USE_STRS As Short
>> Dim USE_ESWL As Short
>> Dim USE_ACN As Short
>> Dim USE_PCR As Short
>> Dim USE_LED As Short
>> Dim spacer1 As Short
>> Dim spacer2 As Short
>> Dim spacer3 As Short
>> End Structure
>>
>> <StructLayout(LayoutKind.Sequential)> Friend Structure typeaircraftdata
>> <MarshalAs(UnmanagedType.LPStr)> Public acName As String
>> Public tires() As typeTireData
>> Dim STDLOAD As Double
>> Dim MAXLOAD As Double
>> Dim MINLOAD As Double
>> Dim PCTM As Double
>> Dim Passes As Double
>> Dim GW As Double ' Load
>> <MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> Public xEval()
>>As Double
>> <MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> Public yEval()
>>As Double
>> Dim NEVAL As Short
>> Dim NTIRES As Short
>> Dim Type As Short
>> Dim spacer2 As Short
>>
>> Public Sub initialize(ByVal vehiclename As String)
>>
>> acName = vehiclename & New String(" ", 120 - vehiclename.Length)
>> ReDim tires(99)
>> ReDim xEval(99)
>> ReDim yEval(99)
>> End Sub
>> End Structure
>>
>>The error occurs as soon as I attemp to call the function. It says system.typeloadexception.
>>Additional information cannot marshal field tires of typeaircraftdata.This
>>type cannot be marshalled as a structure field.
>>>
>>>
>>>When are you getting the error? And what does the Declare statement look
>>>like?
>>>
>>>A few other things to note:
>>>
>>>* You have to use the word "Structure" and not "Struct".
>>>
>>>* Make sure you define what type of String the Name field is (ANSI or
double-byte).
>>>You can do this by using the MarshalAs attribute.
>>>
>>>(at the top of the code file
>>>Imports System.Runtime.InteropServices
>>>
>>>Structure a
>>> <MarshalAs(UnmanagedType.LPStr)> Dim Name As String 'Ansi string
>>>
>>>or
>>>
>>> <MarshalAs(UnmanagedType.LPWStr)> Dim Name As String 'double-byte
string
>>>
>>>-Rob
>>>
>>>
>>>"John Lott" <lottj@wes.army.mil> wrote:
>>>>
>>>>I have a structure A, which contains an array of structure B
>>>>
>>>>IE:
>>>> struct b
>>>> dim x as double
>>>> dim y as double
>>>> end structure
>>>>
>>>> struct a
>>>> dim name as string
>>>> dim myb() as b
>>>>
>>>>I need to pass this to a fortran dll.
>>>>
>>>>The error I am getting is field myb. This type cannot be marshalled as
>>a
>>>>structure.
>>>>
>>>>
>>>
>>
>
-
Re: Accessing a static fortran dll from vb.net
John,
Ouch! Do you often feel like smashing your
keyboard against the wall? 8-)
Pat
"John Lott" <lott@wes.army.mil> wrote:
>
>I found an intermediate solution
>
>I converted the structures to classes and added a funtion called write
>which returns a byte array.
>
>public function write() as byte()
>dim x as new system.io.memorystream
>dim y as new system.io.binarywriter(y)
>
>' write data one variable at a time
> y.write(xcoordinate)
> y.write(ycoordinate)
>' etc etc
> return x.getbuffer()
>end function
>
>
>In the main code
>
>dim intptr as system.intptr
>
> ' 8176 is the size of the array
> intptr = marshal.allochglobal(8176)
>
> marshal.copy(myclass.write(),0,intptr,8176)
>
> myanswer = engmod(intptr)
>
> declare function engmod lib "WesEngMod" (byval intptr as system.intptr)
>as double
>
>
>I am sure there is a better way but I have not been able to find it
>
>"Patrick Ireland" <ireland@airmail.net> wrote:
>>
>>John,
>>
>>I have never had the pleasure of passing a neested structure. However,
>>there is a error in your defintion of typeaircraftdata. You didn't
>>marshall typeTireData in the structure typeaircraftdata. Arrays need to
>>be marshalled when passed to unmanaged code.
>>
>> <MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> _
>> Public tires () as typeTireData
>>
>>I don't have my reference material here so I don't recall whether
>>the sizeconst:= is in bytes or typeTireData size.
>>
>>You will also need to be careful with the acname string.
>>
>>As a pilot, this looks like an interesting application
>>
>>Pat
>>
>>"John Lott" <lottj@wes.army.mil> wrote:
>>>
>>>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>>>
>>>I am using "structure" it was just a typo on the posting
>>>
>>>the declare is as follows
>>>
>>>friend declare sub engmod lib "WesEngMod" (<Marshalas(unmanagedtype.struct)>
>>>byref ac as aircraftdata
>>>
>>>StructLayout(LayoutKind.Sequential)> Friend Structure typeTireData
>>> Dim x As Double
>>> Dim y As Double
>>> Dim Press As Double
>>> Dim CAREA As Double
>>> Dim PHIE As Double
>>> Dim PCTGW As Double
>>> Dim USE_STRS As Short
>>> Dim USE_ESWL As Short
>>> Dim USE_ACN As Short
>>> Dim USE_PCR As Short
>>> Dim USE_LED As Short
>>> Dim spacer1 As Short
>>> Dim spacer2 As Short
>>> Dim spacer3 As Short
>>> End Structure
>>>
>>> <StructLayout(LayoutKind.Sequential)> Friend Structure typeaircraftdata
>>> <MarshalAs(UnmanagedType.LPStr)> Public acName As String
>>> Public tires() As typeTireData
>>> Dim STDLOAD As Double
>>> Dim MAXLOAD As Double
>>> Dim MINLOAD As Double
>>> Dim PCTM As Double
>>> Dim Passes As Double
>>> Dim GW As Double ' Load
>>> <MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> Public xEval()
>>>As Double
>>> <MarshalAs(UnmanagedType.ByValArray, sizeconst:=100)> Public yEval()
>>>As Double
>>> Dim NEVAL As Short
>>> Dim NTIRES As Short
>>> Dim Type As Short
>>> Dim spacer2 As Short
>>>
>>> Public Sub initialize(ByVal vehiclename As String)
>>>
>>> acName = vehiclename & New String(" ", 120 - vehiclename.Length)
>>> ReDim tires(99)
>>> ReDim xEval(99)
>>> ReDim yEval(99)
>>> End Sub
>>> End Structure
>>>
>>>The error occurs as soon as I attemp to call the function. It says system.typeloadexception.
>>>Additional information cannot marshal field tires of typeaircraftdata.This
>>>type cannot be marshalled as a structure field.
>>>>
>>>>
>>>>When are you getting the error? And what does the Declare statement look
>>>>like?
>>>>
>>>>A few other things to note:
>>>>
>>>>* You have to use the word "Structure" and not "Struct".
>>>>
>>>>* Make sure you define what type of String the Name field is (ANSI or
>double-byte).
>>>>You can do this by using the MarshalAs attribute.
>>>>
>>>>(at the top of the code file
>>>>Imports System.Runtime.InteropServices
>>>>
>>>>Structure a
>>>> <MarshalAs(UnmanagedType.LPStr)> Dim Name As String 'Ansi string
>>>>
>>>>or
>>>>
>>>> <MarshalAs(UnmanagedType.LPWStr)> Dim Name As String 'double-byte
>string
>>>>
>>>>-Rob
>>>>
>>>>
>>>>"John Lott" <lottj@wes.army.mil> wrote:
>>>>>
>>>>>I have a structure A, which contains an array of structure B
>>>>>
>>>>>IE:
>>>>> struct b
>>>>> dim x as double
>>>>> dim y as double
>>>>> end structure
>>>>>
>>>>> struct a
>>>>> dim name as string
>>>>> dim myb() as b
>>>>>
>>>>>I need to pass this to a fortran dll.
>>>>>
>>>>>The error I am getting is field myb. This type cannot be marshalled
as
>>>a
>>>>>structure.
>>>>>
>>>>>
>>>>
>>>
>>
>
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks