Hello,
I posted this to m.p.d.languages.vb, but was told this is a better
place to ask (and I worded my question poorly there, so I think I
miss-communicated my question).
What I need to do is send a parameter from VB.net to an Unmanaged C dll
call, and that parameter on the C side is a pointer to unsigned char,
and is assumed to be allocated n bytes (which is also a parameter).
VB.net needs to be able to send an empty Byte() that will be filled by
the DLL. I have access to both the C and the VB.net, so can make
changes in all the appropriate places.
I have attempted to do with with a memcpy and byte by byte with pointer
arithmetic, but I get a stack overflow, or an unbalanced stack message.
Here are some relevant code snippets trying to express what it is I am
attempting:
Unmanaged C DLL code:
int _stdcall getBytes(unsigned char* vbBytes, int alloced, int* filled)
{
int i;
// Hard code for testing
unsigned char cBytes[] = {
0x03, 0x84, 0x44, 0xc1, 0x12, 0x61, 0xb5, 0x4A, 0x21, 0x00,
0xe0, 0x7f, 0xff, 0x00, 0xcb, 0xa9, 0x33, 0x34, 0x7f, 0x4A,
0x01, 0x7f, 0xff, 0x00, 0xca, 0x8f, 0x55, 0x7f, 0x39, 0x1c,
0x4c, 0x23, 0x00, 0xcd, 0x00, 0xaf, 0xc3, 0xc8, 0x00, 0x30,
0x0c, 0x50, 0x00, 0x10, 0x58, 0x03, 0xff, 0x00, 0x01, 0x30,
0x03, 0xdc, 0xe4, 0x9f, 0x4b, 0xd2, 0x66, 0x04, 0x64, 0xc2,
0x1f, 0x00 };
if(alloced < 62)
return 1;
/* This won't work either
for(i = 0; i < alloced; i++)
*(vbBytes++) = *(cBytes++);
*filled = i;
*/
memcpy(vbBytes, cBytes, alloced);
*filled = alloced;
return 0;
}
VB.net:
Private Declare Auto Function getBytes Lib "example.dll" _
(ByRef bytes As Byte(), ByVal alloced As Integer, ByVal
filled As Integer) As Integer
Public Sub getState()
Dim ba(75) As Byte
Dim filled As Integer
getBytes(ba, 74, filled)
For Each b As Byte In ba
Debug.Print(String.Format("0x{0:x2}", b))
Next
End Sub
Mattias Sjögren - 13 Jan 2007 09:17 GMT
Vince,
>I posted this to m.p.d.languages.vb, but was told this is a better
>place to ask (and I worded my question poorly there, so I think I
>miss-communicated my question).
I thought it was pretty clear the first time. And my answer is still
that you need to pass the Byte aray ByVal.
Mattias

Signature
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Vince Castellano - 15 Jan 2007 17:27 GMT
> I thought it was pretty clear the first time. And my answer is still
> that you need to pass the Byte aray ByVal.
I tried this, and got a 'System.AccessViolationException'. Therefore, I
had assumed that you thought I meant sending data from the VB.net
application to the DLL, where what I wanted was just to send an array
from VB.net to the C DLL to be filled, and then used by VB.net.
What would be the correct way on the DLL side to fill this array when
passed ByVal, as memcpy does not seem to work still.
Thank you for your help,
Vince
Mattias Sjögren - 16 Jan 2007 06:39 GMT
Vince,
>I tried this, and got a 'System.AccessViolationException'.
Probably due to a bug in your C code, not a marshaling failure.
for(i = 0; i < alloced; i++)
should be
for(i = 0; i < 62; i++)
Mattias

Signature
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Vince Castellano - 15 Jan 2007 21:46 GMT
Mattias,
> Mattias Sjögren [C# MVP] mattias @ mvps.org
> http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
> Please reply only to the newsgroup.
Sorry for the double post, but I looked into the URL
(http://www.dotnetinterop.com) in your signature, and I found
information that worked for me there.
Turned out if I sent it ByVal an IntPtr, and then used the Marshal
functions to allocate and pull bytes out, it worked fine. I was unaware
of the Marshal class, so I did not do this before. Now I just redim my
Byte() the size filled (usually but not always equal to alloced), and
pull out the bytes using Marshal.ReadByte(pCurrent) one by one.
Thank you again for your time, and I hope that if any one else has this
issue, this post will have enough info to help.
Vince Castellano