Re: Call C DLL from VB.net-problem..array gains 4 bytes!
- From: "Paul G. Tobey [eMVP]" <ptobey no spam AT no instrument no spam DOT com>
- Date: Thu, 30 Jun 2005 10:02:39 -0700
You shouldn't be passing fixed-size arrays around between managed and
unmanaged code, in my opinion. That is, the 'right' declarations, according
to me are a managed code interface as a function, which will verify the
array layout before calling to C, and a size-independent declaration for the
C/C++ DLL.
That is, you're expecting an array of a given size in your C/C++ DLL. Use
managed code wrapping around the DLL to verfiy that things are the right
size, then call the C DLL, but call a correct declaration of the function
(passing a generic 'pointer' to the data, not a fixed-size array). Note
that I don't try to write DLL communication stuff in VB.NET, so here's
something in C#, more or less:
class whatever
{
[DllImport ("mydll.dll")]
private static extern int MyCFunction( byte[] param1, int[] param2, int
param3 );
public static int MyCFunctionWrapper( byte[] param1, int[] param2, int
param3 )
{
// First, make sure that the array parameters have the correct
lengths to match the
// C/C++ code that we'll be calling.
if ( param1 == null )
{
// Use passed null array. Not such a good idea to pass that
along
// to C/C++. Throw exception instead.
throw new Exception( ... );
}
if ( param1.Length != PARAM1_ARRAY_LEN )
{
// The user passed us an array that will likely crash C/C++.
Throw
// an exception instead.
throw new Exception( ... );
}
// Check the other array, too.
// OK, the arrays are fine. Call into the DLL.
return MyCFunction( param1, param2, param3 );
}
}
class callingclass
{
methodwhatever
{
byte[] param1 = new byte[ PARAM1_ARRAY_LEN ];
int[] param2 = new int[ .... ];
return whatever.MyCFunctionWrapper( param1, param2, 45 );
}
}
Paul T.
"Bill" <Bill@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:A3EBA041-388D-4B10-9EA8-D5AD2D05B462@xxxxxxxxxxxxxxxx
> I've a problem regarding a call to a native DLL from VB.NET (running on
> windows CE 4.2 on IPAQ).
>
> Although the call succeeds there appears to be an anomaly with the size
> and
> content of one of the byte arrays I am passing. (there was also a problem
> with the order of the parameters)
>
> While I have worked round both of these problems. I am nervous about my
> lack
> of understanding of the underlying issues and would be grateful if someone
> could enlighten me.
>
> PROBLEM 1... The DLL gets an extra 4 bytes at the front of the array that
> "appear" to indicate its size... but only for the large array (64 bytes)
>
> The VB end is this (abbreviated and hacked about here)
>
> All of the below is within the same class except for keyvalue
>
> Public keyValue(7) As Byte ' this is global
>
> Private SealArray(63) As Byte ' this is within the same class as the
> function calling the dll
> ....
> .
> .
> Dim newSeal(8) As Byte ' yes I know this should be (7) ..see later
>
> CalculateSeal(SealArray, newSeal) 'call into fn calling the DLL
> .
> .
> <DllImport("thisDll.dll")> Public Function fnThisFunctionInDLL(ByVal s
> As Byte(), ByVal sk As Byte(), ByVal sr As Byte(), ByVal ithisInt As
> Integer)
> As UInt32
> End Function
>
> Public Function CalculateSeal(ByVal InArray() As Byte, ByVal OutArray()
> As Byte)
>
> Dim ui32ret As UInt32
> Dim ithisInt As Integer = 0
>
> ui32ret = fnThisFunctioninDLL(InArray, OutSeal, keyValue, ithisint)
> ' DLL call is HERE
>
> Return (True)
> End Function
>
> .
> .
> .
> '------------------------------------------------------------------------------
> The C DLL has this prototype
>
> extern "C" KEYDIVCE_API WORD fnThisFunctionInDLL(BYTE byaULData[64],
> BYTE byaSeal[8],
> BYTE
> pbyKeyFile[8],
> unsigned
> int
> ithisInt);
>
> ----------------------------------------------------------------------------------
> basically...
> we are passing in two bytes arrays (byaULData.. 64 bytes and pbyKeyFile ..
> 8bytes
> we get back the returned 8 byte array in byaSeal. The integer merely
> affects
> the code flow in the dll
>
> The problem is this.... byaULData should contain AA BB CC DD EE FF.....
> but actually arrives in the DLL containing 0x40 00 00 00 AA BB CC DD EE
> ....
>
> it looks like the 1st 4 bytes contain the size of the array.
> However the 8 byte arrays do not seem to have any header!
>
> Chop off the 1st 4 bytes of the 64 byte array and it works.
>
> I am sure that in casual reading some time back I came across "something"
> about this but cannot for the life of me remember where. The documentation
> I
> have gone through in the last implies that blittable data types (and their
> arrays) can simply be passed "as is"
>
> All help gratefully recieved.
> NOTE I know the 1st parameter is actually 9 bytes.. this is an error that
> will be fixed but does not appear to disturb the code ( another call to
> the
> same fn later with the correct (7) works the same way)
>
> PROBLEM 2
>
> Much simpler (!) Placing the integer as the third parameter instead of the
> fourth seems to completely wreck the data !
>
> This code is running on an IPAQ (windows CE 4.2) and the development
> environment is windows 2000 running Visual Studio.net 2003.
>
> My apologies about the length of this post.
> Regards
> Bill
>
>
>
>
>
.
- References:
- Prev by Date: Re: Automatic Start of Powerpoint presentation on WinCE 4.2
- Next by Date: Re: Automatic Start of Powerpoint presentation on WinCE 4.2
- Previous by thread: RE: Call C DLL from VB.net-problem..array gains 4 bytes!
- Index(es):
Relevant Pages
|