Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / February 2008

Tip: Looking for answers? Try searching our database.

Array of Structures

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
DLI - 08 Feb 2008 19:10 GMT
I have to port some VBA Code to VB DotNet

The following code block defines several types in VBA.

Public Type ProbParamKind

 Na As Long

 Nc As Long

 Nstep As Long

 MaxCycles As Long

 AxialPts As Long

End Type

Public Type RunOptKind

KeyProdID As Long

KeyImpID As Long

KeyProdSpec As Double

KeyImpSpec As Double

RecoveryTarget As Double

PurgeFactor As Double

CoCurCutOff As Double

BedSizeFactor As Double

BedVol As Double

BedLen As Double

TempWall As Double

NonAdiabaticFrac As Double

ISOmodel(1 To 8) As Byte 'Array of bytes representing IsoModel As String *
8

End Type

Public Type GasKind

 GasID(1 To 8) As Byte   'Array of bytes representing  GasID As String * 8

 Mw As Double

 CpPar(1 To 4) As Double

 MuPar(1 To 2) As Double

 LmdaPar(1 To 3) As Double

End Type

It makes a call to a fortran dll using arrays of these types and a long to
return an error code.

Public Declare Sub PSAEngine Lib "PSAxEngine.dll" ( _

ProbParam As ProbParamKind, RunOpt As RunOptKind, _

Gases As GasKind, ByRef errFlag As Long)

It works fine.

I have defined these structures in VB DotNet that match the types in VBA

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> Public
Structure ProbParamKind

       Dim Na As Int32

       Dim Nc As Int32

       Dim Nstep As Int32

       Dim MaxCycles As Int32

       Dim AxialPts As Int32

End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> Public
Structure RunOptKind

       Dim KeyProdID As Int32

       Dim KeyImpID As Int32

       Dim KeyProdSpec As Double

       Dim KeyImpSpec As Double

       Dim RecoveryTarget As Double

       Dim PurgeFactor As Double

       Dim CoCurCutOff As Double

       Dim BedSizeFactor As Double

       Dim BedVol As Double

       Dim BedLen As Double

       Dim TempWall As Double

       Dim NonAdiabaticFrac As Double

       <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Dim ISOmodel()
As Byte

   End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> Public
Structure GasKind

       <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Dim GasID() As
Byte

       Dim Mw As Double

       <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim CpPar() As
Double

       <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Dim MuPar() As
Double

       <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim LmdaPar() As
Double

End Structure

Here is the dotnet call definition

Public Declare Sub PSAEngine Lib "PSAxEngine.dll" ( _

       ByRef ProbParam As ProbParamKind, ByRef RunOpt As RunOptKind, _

       ByRef Gases As GasKind, ByRef errFlag As Int32)

Here is the call in code

Call PSAEngine(ProbParam, RunOpt, Gases(0), errFlag)

When I try to use the same fortran dll with matching arrays, I get junk
after the first element of the array of GasKind.

Gases is loaded correctly with 10 elements in the code before the call.

The first element contains the data I set to be passed in. Starting with the
second element, elements contain jibberish (and it differs from one
execution to the next I might add so I don't think it is just a shift of
position).

Can anyone give me a hint as to what I have missed?

I think the second element of the GasKind array is being read from the wrong
memory address but I can't tell why.
DLI - 14 Feb 2008 17:56 GMT
In regards to this posting, I did google this thread:

http://www.dotnet247.com/247reference/msgs/43/215864.aspx

The following quote is from that very long thread

The marshaller cannot handle "embedded arrays of structures" and "variable

length structs". It can only handle embedded arrays of blittable types(int,

char etc) - as I illustrated in a previous post.

If you really want to use C# to pass such managed structures to unmanaged

code, you'll need to help the marshaller by passing as argument to the API,

a pointer to a buffer, that contains a copy of the managed struct fields you

marshalled using the Marshal.WriteXX methods. On return you need to copy the

buffer contents back to the managed structure using the Marshal.ReadXX

Does anyone know if this has been changed in Visual Studio 2005?

Would we still have to use Marshal.WriteXX methods to pass an array of
structures to un-managed dll?

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.