[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

VB.NET / DLL structure passing

sam

6/7/2007 11:45:00 PM

I have a third-party DLL (unmanaged) for which I am trying to call a
function. The function requires a structure (as an argument) which
utilized several variables I am unable to translate.

The original C header structures contain (amongst other things that I
have already translated):


typedef byte TPacketType[int(100)];

struct TModuleRec
{
/*1 byte*/ bool Succeeded;
/*4 bytes*/ char *Error;
/*4 bytes*/ char *ProjectFiles[7];
/*4 bytes*/ int ProjectFilesStart[7];
byte EEPROM[50];
TPacketType PacketBuffer;
}

I've been able to translate everything so far except for these
particular variables. I've tried (as suggested on some interop articles
I've read)

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> Public
Class TPacketType
Public TPacketType(100) As Byte
End Class

<StructLayout(LayoutKind.Sequential)> Public Class TModuleRec
<MarshalAs(UnmanagedType.U1)> Public Succeeded As Boolean
Public Err(4) As Byte
Public ProjectFiles(7) As Byte
Public ProjectFilesStart(7) As Integer
Dim EEPROM(50) As Byte
Public EEPROMFlags(50) As Byte
Public PacketBuffer As TPacketType
End Class


for the booleans, but this still results in "non-primitive or
non-blittable" structure errors (I remarked out the unmarshalled Bools
during testing).

I'd really like to understand why the MarshalAs isn't working (as well
as how to translate the other lines). Can someone offer some suggestions?
2 Answers

Ben Voigt [C++ MVP]

6/9/2007 5:51:00 PM

0


"sam" <spammenot@gtnincs.com> wrote in message
news:uJF1p3VqHHA.3356@TK2MSFTNGP03.phx.gbl...
>I have a third-party DLL (unmanaged) for which I am trying to call a
>function. The function requires a structure (as an argument) which utilized
>several variables I am unable to translate.
>
> The original C header structures contain (amongst other things that I have
> already translated):
>
>
> typedef byte TPacketType[int(100)];
>
> struct TModuleRec
> {
> /*1 byte*/ bool Succeeded; /*4 bytes*/ char *Error;
> /*4 bytes*/ char *ProjectFiles[7];

You have an array of pointers, which I don't believe .NET can handle, never
mind VB.

You can make this an array of IntPtr, and use Marshal to pin the objects and
fill in all the pointers yourself, or you could write a .NET compatible
wrapper with C++/CLI. The latter is usally much easier, if you have ever
used C or C++ before.

> /*4 bytes*/ int ProjectFilesStart[7];
> byte EEPROM[50];
> TPacketType PacketBuffer;
> }
>
> I've been able to translate everything so far except for these particular
> variables. I've tried (as suggested on some interop articles I've read)
>
> <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> Public Class
> TPacketType
> Public TPacketType(100) As Byte
> End Class
>
> <StructLayout(LayoutKind.Sequential)> Public Class TModuleRec
> <MarshalAs(UnmanagedType.U1)> Public Succeeded As Boolean
> Public Err(4) As Byte
> Public ProjectFiles(7) As Byte
> Public ProjectFilesStart(7) As Integer
> Dim EEPROM(50) As Byte
> Public EEPROMFlags(50) As Byte
> Public PacketBuffer As TPacketType
> End Class
>
>
> for the booleans, but this still results in "non-primitive or
> non-blittable" structure errors (I remarked out the unmarshalled Bools
> during testing).
>
> I'd really like to understand why the MarshalAs isn't working (as well as
> how to translate the other lines). Can someone offer some suggestions?

sam

6/9/2007 8:50:00 PM

0


> You can make this an array of IntPtr, and use Marshal to pin the objects
> and fill in all the pointers yourself, or you could write a .NET
> compatible wrapper with C++/CLI. The latter is usally much easier, if
> you have ever used C or C++ before.


After looking for resources on this sort of thing for several days, it
sound like your suggestion of writing a C++ wrapper for this thing might
be the way to go. I can find no examples of something like this on the
web, and every example I do find of marshalling seems to fail with
errors--there appear to be quite a few pratfalls involved. I have some
C++ experience, but writing a managed wrapper might be a better way to
go. I've considered it. Another thing I've considered--I don't even know
if it's possible--is to build a byte array of all this data and then
pass the pointer.