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 7 16805
> *** 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.
"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.
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.
"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
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
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
> 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 :) This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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;...
|
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...
|
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...
|
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( ){
|
by: shobu |
last post by:
passing array checkbox value and update the database <?include 'dbconnect.php'; error_reporting(0);$update_qr="update...
|
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.
|
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...
|
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...
|
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
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
| |