Re: Call C DLL from VB.net-problem..array gains 4 bytes!



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
>
>
>
>
>


.



Relevant Pages

  • Re: Call C DLL from VB.net-problem..array gains 4 bytes!
    ... Remember the DLL declaration... ... I still have not found where it says a byte array ... > array layout before calling to C, and a size-independent declaration for the ...
    (microsoft.public.windowsce.app.development)
  • Re: Is a Thread appropriate?
    ... >> Now, if you are not doing dynamic loading of the DLL, you shouldn't need GetProcAddress. ... >> Note that it is foolish to create a char array, particularly a char array of a fixed size. ... >> If you need to declare a separate variable, ... without necessity. ...
    (microsoft.public.vc.mfc)
  • Re: VB .Net and Intel Visual Fortran 9
    ... having is that the VB program cannot load the DLL. ... subroutine) to accept an array from VB - in my case a 2D array. ... Declare Sub mmult Lib "test.dll" (ByRef i As Double, ByRef j As Double, ...
    (comp.lang.fortran)
  • Re: Marshalled structure size
    ... but unfortunately I don't have access to the DLL ... > odd index (int) element would be mis-aligned on an odd address, ... > I would suggest you inspect the C code and check how the array gets ... >>> The 32 comes from the fact that the interop marshaler reserves a buffer ...
    (microsoft.public.dotnet.languages.csharp)
  • VB .Net and Intel Visual Fortran 9
    ... having is that the VB program cannot load the DLL. ... subroutine) to accept an array from VB - in my case a 2D array. ... Declare Sub mmult Lib "test.dll" (ByRef i As Double, ByRef j As Double, ...
    (comp.lang.fortran)