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 / August 2006

Tip: Looking for answers? Try searching our database.

String array in c++ dll  to vb.net

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jeremy - 24 Aug 2006 11:24 GMT
Hello,

I have an unmanaged  c++ dll which exports the  function:

long GetAllFormationNames(long LithSchemeID, long LevelID,  int &
numData, long ** Ids, char *** Names);

it's the final argument that I am having trouble converting/calling
from VB.NET - everything I have tried has resulted in either an array
containing rubbish or an array with 1 element containing only the
first element that *should* be returned

I am rather new to the .Net thing - so be gentle!

Jeremy
TDC - 24 Aug 2006 13:11 GMT
No problem, but first a few questions:

Do you know how many names will be returned?  Are you supposed to
allocate buffers for the data to be populated does the dll allocate the
memory for the Strings (and you must have to free it later)?

Tom

> Hello,
>
[quoted text clipped - 11 lines]
>
> Jeremy
Jeremy - 25 Aug 2006 11:04 GMT
Hi,

1. I don't know in advance how many names will be returned - the
returned parameter numData is the number of names returned..

2.. the dll allocates the memory for the strings.

hope that makes it clearer!

Regards,

Jeremy

>No problem, but first a few questions:
>
[quoted text clipped - 19 lines]
>>
>> Jeremy
TDC - 25 Aug 2006 13:30 GMT
It certainly does.

Here is what I recommend.  Pass a ByRef IntPtr to the Names parameter.

This will get you the address of the array.  Of course, this array is
really a continuous block of memory that has consecutive pointers to
your strings (char arrays).

You can use Marshal.ReadIntPtr(ptr, offset) to walk the array and get
the IntPtrs to the actual data.

>From those IntPtrs you can use Marshal.PtrToStringAnsi (or one of the
other Marshal.PtrToStringXXX methods) to get a .NET String.

Don't forget to call whatever method the dll provides to free the
memory is allocated for this call.

Tom

> Hi,
>
[quoted text clipped - 32 lines]
> >>
> >> Jeremy
Jeremy - 25 Aug 2006 15:00 GMT
OK - I tried this:

>Dim formations As String()
>Dim r As Long
[quoted text clipped - 7 lines]
>
>formations(0) = Marshal.PtrToStringAuto(ip)

the resulting string looks like rubbish though (I tried the other
PtrToStringxxx functions too) ...

I know the dll function works btw as I can call it from C++

hmm.. any more ideas?

Cheers,

Jeremy

>It certainly does.
>
[quoted text clipped - 51 lines]
>> >>
>> >> Jeremy
Christian Fröschlin - 25 Aug 2006 15:49 GMT
>>r = GetAllFormationNames(1, 2, numdata, ids, ip)
>>
>>ReDim formations(numdata)
>>
>>formations(0) = Marshal.PtrToStringAuto(ip)

You missed one level of indirection: ip does not point
to string data, it points to the array of char pointers.
Try Marshal.PtrToStringAuto(Marshal.ReadIntPtr(ip,0)).
TDC - 25 Aug 2006 16:14 GMT
Jeremy, Christian is correct (though you'd eventually put it in a for
loop to get all the strings, not just the first one).

By the way, a C++ longs is an VB Integer (or Int32 or UInt32) in .NET
so you have another slight error.

Tom

> >>r = GetAllFormationNames(1, 2, numdata, ids, ip)
> >>
[quoted text clipped - 5 lines]
> to string data, it points to the array of char pointers.
> Try Marshal.PtrToStringAuto(Marshal.ReadIntPtr(ip,0)).
Jeremy - 25 Aug 2006 16:35 GMT
Aha - now we are getting there..

I can now get a whole array of strings back like this:

>r = GetAllFormationNames(1, 2, numdatap, idsp, ipp)
>
[quoted text clipped - 14 lines]
>            Next
>        End If

however at (seemingly) random points in the formationnames array I get
short (1 or 2 chars) strings of characters with ascii values over 128
- I originally tried incrementing offset by the value of the last
string found instead of by 1, but then I found that a lot of the
elements of formationnames were empty..

..I can write a check to ensure that the strings returned are
alphanumeric, but that's a rather ugly solution!

anyway - thanks for the help in getting to this point!

Jeremy

>>>r = GetAllFormationNames(1, 2, numdata, ids, ip)
>>>
[quoted text clipped - 5 lines]
>to string data, it points to the array of char pointers.
>Try Marshal.PtrToStringAuto(Marshal.ReadIntPtr(ip,0)).
TDC - 25 Aug 2006 16:45 GMT
I think offset is a byte-offset as opposed to an IntPtr-width offset.
In other words, since an IntPtr is 4 bytes, increment the offset by 4
each time.

Tom

> Aha - now we are getting there..
>
[quoted text clipped - 41 lines]
> >to string data, it points to the array of char pointers.
> >Try Marshal.PtrToStringAuto(Marshal.ReadIntPtr(ip,0)).
TDC - 25 Aug 2006 16:50 GMT
Just noticed your while...I don't know why that is there.  It should
look more like this:

For ndx as Integer = 0 to numOfNames -1

  formationnames(ndx) =
Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(ptr, offset))
  offset += 4

Next ndx

Tom
TDC - 28 Aug 2006 13:12 GMT
Jeremy,

Be sure to let us know how you made out.  That way everyone can learn
what works and what doesn't.

Tom

> Just noticed your while...I don't know why that is there.  It should
> look more like this:
[quoted text clipped - 8 lines]
>
> Tom

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.