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

Tip: Looking for answers? Try searching our database.

In/Out strings and explicit P/Invoke

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
chris_nusca@hotmail.com - 24 May 2006 20:29 GMT
Hi.

My apologies if this question is trivial, I couldn't find the answers
on MDSN and it's the first time I've worked with input/output strings
across explicit P/Invoke.

My question is about memory management of input/output strings using
explicit P/Invoke.

Basically I send a fixed-size array of empty strings across P/Invoke
and the C++ library needs to populate the individual strings with data
of various lengths to be returned back up to the caller.  The C++
library is NOT compliled with any "/clr" options.

Here's the C# declaration:

[DllImport("my.dll")]
internal extern static void MyMethod(
 [In][Out][MarshalAs(UnmanagedType.LPArray,
ArraySubType=UnmanagedType.LPStr, SizeConst=2)]
 String[] messages,
 int numberOfMessages);

Here's the C++ declaration:

extern "C" __declspec(dllexport)
void MyMethod(
 char* messages[],
 int numberOfMessages);

Who is responsible for memory management of the individual strings -
CLR or C++ library?

Does the C++ library have to perform new/delete on each string?

If not, do I have to explicitly pass string lengths across P/Invoke to
avoid C++ buffer overrun?

Currently the code crashes when the C++ library uses strcpy() copy data
into the output strings.

Thanks very much for your help.

Chris Nusca
Bob Eaton - 25 May 2006 13:49 GMT
I'm not sure if this is *necessary*, but a better (read: safer) way to do
this is having your DLL return a SAFEARRAY of type BSTR. Here's a snippet
I've used (I don't know how to do it without ATL helper classes, though):

// on the C++ side, define your method as:

// in .cpp file implementation:
SAFEARRAY* MyMethod()
{
 CComSafeArray<BSTR>* pSa = new CComSafeArray<BSTR>();

 int nSize = numberOfMessages;
 pSa->Create(nSize);

 for(int i = 0; i < nSize; i++ )
 {
   // create "system" memory for returning back to caller (using CComBSTR)
   CComBSTR strName = messages[i];
   pSa->SetAt(i,strName);
 }

 return pSa->Detach();
}

// then on the .Net side, you can use:
   string [] aMessages = MyMethod();

To get the returned string array back correctly.

I've left out some details because I'm not sure whether this works the same
for a DllImport vs. the way I use it--as a method of a COM class),
but I hope this gives you the hint you need.

Bob

> Hi.
>
[quoted text clipped - 40 lines]
>
> Chris Nusca
chris_nusca@hotmail.com - 25 May 2006 19:36 GMT
Thanks Bob.

I was hoping to stick with just ANSI strings (i.e. char* ).  I'm
actually contemplating using char[MAX_PATH] instead of char* which
would make everything blittable and hopefully easier.  If I can't get
that working I'll probably revert to your suggestion.   Either way I'll
provide an update.

Regards
Chris
chris_nusca@hotmail.com - 29 May 2006 06:43 GMT
Hi,

I found the solution which is to explicitly pre-allocate the strings in
.NET as follows:

  // do this for every input/output string
  messages[i] = new String('\0', 256);

The C++ library receives a buffer of (256+1) characters which can be
read/written. The CLR handles allocation and deletion, so the only
extra work is to pass an extra input parameter containing the buffer
size.

Here is a nice MSDN article on the subject:
  http://msdn2.microsoft.com/en-us/library/s9ts558h(VS.80).aspx

Regards,
Chris

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.