Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / January 2007

Tip: Looking for answers? Try searching our database.

Need a method to send byte arrays from Unmanaged C DLL to VB.Net

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Vince  Castellano - 12 Jan 2007 23:55 GMT
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

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.