473,387 Members | 1,844 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

vb.net Marshalling: Passing array of structure to dll

Does anyone know how to pass an array of structures to a DLL? Here's what
I'm doing... the VB.Net error is at the end.
*** C++ Structure Declaration:

typedef struct _SOME_STRUCT
{
char *pId;
char *pBuffer;
DWORD dwBufferLength;
DWORD dwBytesReturned;
DWORD dwStatus;
} SOME_STRUCT;

*** C++ Function Prototype:
SOME_API ULONG _stdcall GetData (char *pDevName, SOME_STRUCT *pSomeStruct,
unsigned long dwTotalStructs);
*** VB.NET Structure Declaration:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure TEST_SOME_STRUCT
<MarshalAs(UnmanagedType.LPStr)> Public URL As String
<MarshalAs(UnmanagedType.LPArray)> Public Buffer() As Byte
<MarshalAs(UnmanagedType.U4)> Public BufferLength As Int32
<MarshalAs(UnmanagedType.U4)> Public BytesReturned As Int32
<MarshalAs(UnmanagedType.U4)> Public Status As Int32

Public Sub New(ByVal URL As String, ByVal BufferLength As Integer)
Me.URL = URL
Me.BufferLength = BufferLength
ReDim Buffer(BufferLength - 1)
End Sub
End Structure

*** VB.NET DLL Prototype (declaration):

<DllImport("mtmcrapi.dll")> Protected Shared Function GetData(<[In]()> ByVal
DeviceName As String, <MarshalAs(UnmanagedType.LPArray), [In](), Out()> ByRef
Info() As TEST_SOME_STRUCT, <[In]()> ByVal StructCount As Int32) As Int32
End Function

*** VB.NET Code that produces the error:

Dim MyBuffers() As TEST_SOME_STRUCT
ReDim MyBuffers(1)
MyBuffers(0) = New TEST_SOME_STRUCT("anyUrl1", 1024)
MyBuffers(1) = New TEST_SOME_STRUCT("anyUrl2", 4096)
Dim rc as Int32 = GetData(mDeviceName, MyBuffers, 2)

*** VB.NET Error:
An unhandled exception of type 'System.TypeLoadException' occurred in
MyApp.exe

Additionaql information: Can not marshal field Buffer of type
TEST_SOME_STRUCT: This type can not be marshaled as a structure field.

--
Mick
Jul 21 '05 #1
7 16796
> *** VB.NET Structure Declaration:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure TEST_SOME_STRUCT
<MarshalAs(UnmanagedType.LPStr)> Public URL As String
<MarshalAs(UnmanagedType.LPArray)> Public Buffer() As Byte
<MarshalAs(UnmanagedType.U4)> Public BufferLength As Int32
<MarshalAs(UnmanagedType.U4)> Public BytesReturned As Int32
<MarshalAs(UnmanagedType.U4)> Public Status As Int32

Public Sub New(ByVal URL As String, ByVal BufferLength As Integer)
Me.URL = URL
Me.BufferLength = BufferLength
ReDim Buffer(BufferLength - 1)
End Sub
End Structure
You should be able to define pBuffer as StringBuilder since its a variable
length string.

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure TEST_SOME_STRUCT
<MarshalAs(UnmanagedType.LPStr)> Public URL As String
Public Buffer As System.Text.StringBuilder
<MarshalAs(UnmanagedType.U4)> Public BufferLength As Int32
<MarshalAs(UnmanagedType.U4)> Public BytesReturned As Int32
<MarshalAs(UnmanagedType.U4)> Public Status As Int32
Public Sub New(ByVal URL As String, ByVal BufferLength As Integer)
Me.URL = URL
Me.Buffer = New System.Text.StringBuilder(BufferLength)
End Sub
End Structure
* *** VB.NET DLL Prototype (declaration):
<DllImport("mtmcrapi.dll")> Protected Shared Function GetData(<[In]()> ByVal DeviceName As String, <MarshalAs(UnmanagedType.LPArray), [In](), Out()> ByRef Info() As TEST_SOME_STRUCT, <[In]()> ByVal StructCount As Int32) As Int32
End Function


Try declaring the function as:
<DllImport("mtmcrapi.dll")> Protected Shared Function _
GetData(ByVal DeviceName As String, _
<[In], Out> ByVal Info() As TEST_SOME_STRUCT, _
ByVal StructCount As Int32) As Int32
End Function

hope that helps..
Imran.
Jul 21 '05 #2


"Imran Koradia" wrote:
Try declaring the function as:
<DllImport("mtmcrapi.dll")> Protected Shared Function _
GetData(ByVal DeviceName As String, _
<[In], Out> ByVal Info() As TEST_SOME_STRUCT, _
ByVal StructCount As Int32) As Int32
End Function
hope that helps..
Imran.

Thanks for the suggestion Imran, but whether it is declared ByRef or ByVal,
I get the same result.

Jul 21 '05 #3
Did you change the Buffer field to StringBuilder (or something else)? I
believe you cannot mark fields with the UnmanagedType.LPArray attribute.
Either use the Stringbuilder or use an IntPtr and then use Marshal.Copy to
convert back and forth.

hope that helps..
Imran.

"Mick" <Mi**@discussions.microsoft.com> wrote in message
news:1E**********************************@microsof t.com...


"Imran Koradia" wrote:
Try declaring the function as:
<DllImport("mtmcrapi.dll")> Protected Shared Function _
GetData(ByVal DeviceName As String, _
<[In], Out> ByVal Info() As TEST_SOME_STRUCT, _
ByVal StructCount As Int32) As Int32
End Function
hope that helps..
Imran.
Thanks for the suggestion Imran, but whether it is declared ByRef or

ByVal, I get the same result.

Jul 21 '05 #4
"Imran Koradia" wrote:
Did you change the Buffer field to StringBuilder (or something else)? I
believe you cannot mark fields with the UnmanagedType.LPArray attribute.
Either use the Stringbuilder or use an IntPtr and then use Marshal.Copy to
convert back and forth.

hope that helps..
Imran.


I have tried StringBuilder. I'm not certain, but because the buffer can be
populated with data that can contain byte values of zero (0), I believe this
would not be an acceptable solution. If this is not correct, please let me
know.

I believe the IntPtr may work, but in order to use an IntPtr, I would need
to declare and allocate space for a byte array, and then have the IntPtr
point to the address of the first element of that byte array so the dll call
could populate it. Do you know how I might accomplish this?

The function call requires that I pass a pointer to an allocated buffer.

Mick
Jul 21 '05 #5
Try this:

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure TEST_SOME_STRUCT
<MarshalAs(UnmanagedType.LPStr)> Public URL As String
Public BuffPtr As IntPtr
<MarshalAs(UnmanagedType.U4)> Public BufferLength As Int32
<MarshalAs(UnmanagedType.U4)> Public BytesReturned As Int32
<MarshalAs(UnmanagedType.U4)> Public Status As Int32
Public Sub New(ByVal URL As String, ByVal BufferLength As Integer)
Me.URL = URL
Me.BuffPtr = Marshal.AllocHGlobal( _
Marshal.SizeOf(GetType(Byte))*BufferLength)
End Sub
End Structure

Then use Marshal.Copy to retrieve the byte array:
Dim buff( ) As Byte

Marshal.Copy(MyBuffers(0).BuffPtr, buff, 0, MyBuffers(0).BufferLength)

hope that helps..
Imran.

"Mick" <Mi**@discussions.microsoft.com> wrote in message
news:BC**********************************@microsof t.com...
"Imran Koradia" wrote:
Did you change the Buffer field to StringBuilder (or something else)? I
believe you cannot mark fields with the UnmanagedType.LPArray attribute.
Either use the Stringbuilder or use an IntPtr and then use Marshal.Copy to convert back and forth.

hope that helps..
Imran.

I have tried StringBuilder. I'm not certain, but because the buffer can

be populated with data that can contain byte values of zero (0), I believe this would not be an acceptable solution. If this is not correct, please let me know.

I believe the IntPtr may work, but in order to use an IntPtr, I would need
to declare and allocate space for a byte array, and then have the IntPtr
point to the address of the first element of that byte array so the dll call could populate it. Do you know how I might accomplish this?

The function call requires that I pass a pointer to an allocated buffer.

Mick

Jul 21 '05 #6
GREAT!!!

That worked...

I added a readonly property to return the byte array. I had to deminsion
the byte array before the copy, and I went ahead and released the memory
allocated for the buffer after copying the array.

Thanks very much for your help Imran.

Mick

Jul 21 '05 #7
> That worked...

cool !
I added a readonly property to return the byte array. I had to deminsion
the byte array before the copy, and I went ahead and released the memory
allocated for the buffer after copying the array.
yup - I forgot the minute details ;-) But surely you do need to release the
unmanaged memory since the GC isn't aware of unmanaged allocations.

Thanks very much for your help Imran.


glad to help :)
Jul 21 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Raju V.K | last post by:
I am developing a web site which requires a set og unique values be transferred between pages and server many times. There fore i decided to put the values in an array so that only one reference to...
4
by: Animesh | last post by:
Hi All, I don't know whethher this is possible or not. This is the result of a bad design problem. Here I go; I have a structure like this: typedef struct _s_index_entry { char *doc_id;...
7
by: Mick | last post by:
Does anyone know how to pass an array of structures to a DLL? Here's what I'm doing... the VB.Net error is at the end. *** C++ Structure Declaration: typedef struct _SOME_STRUCT { char...
7
by: Jake Thompson | last post by:
Hello I created a DLL that has a function that is called from my main c program. In my exe I first get a a pointer to the address of the function by using GetProcAddress and on the dll side I...
9
by: nano2 | last post by:
Hi , Have the following case passing in structure pointers and returning structure pointers can anyone spot whats wrong with this structure name is structCar void callfn( ){
3
by: shobu | last post by:
passing array checkbox value and update the database <?include 'dbconnect.php'; error_reporting(0);$update_qr="update...
1
by: sharadvasista | last post by:
I have a structure typedef struct t_abcd { int a; int b; int c; } abcd; I have to pass the structure to another function. I can do this in two ways.
2
by: calenlas | last post by:
Hi all, I'm taking my first steps into C# <--C++ DLL Interop and unfortunately I've run into (what seems to be) a very complicated case as my first task. Perhaps someone here can help me. I...
1
by: dissectcode | last post by:
Hello - Please tell me what this is...It looks like an array/structure/prototype/pointer... STATIC void *_aname = { { &d0, &d1 } , { &d10, &d11 } } ; i've never seen this before please...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.