Fog Creek Software
Discussion Board

Welcome! and rules

Joel on Software

Marshalling a string return to C#

Does anyone know how to Marshal a string value return from unmanaged code?

So in C++ we have:

extern "C" __declspec(dllexport) const char* SpecsGetSegmentList() {
    return GlobalWorldSpec->GetSegmentList().c_str();

On the C# side I've tried stuff like:

    [return : MarshalAs( UnmanagedType.LPStr )]
    public static extern string SpecsGetSegmentList();

But I can't seem to get it to work.  There are tons of examples of passing strings TO unamanged code, but I can't seem to find any for getting one back.


David Whatley
Friday, February 14, 2003

David, this helped me when I was doing interop a while back:

*Lots* of useful things in the Marshal class.

Duncan Smart
Friday, February 14, 2003

Hey thanks!  That actually got me on the right track.  I can't BELIEVE how unintuitive returning a string is... the documentation leads you to believe It Just Works.  And then they have all these things about converting strings... but I never saw that technique used.

At first if failed, but that turned out to be because the string was not in the heap.  Another obscurity that makes sense only when you really know what's going on behind the scenes.

Here is my modified version that works:

How To Return A String from C++ to C#
(title for the benefit of Google to find this for others)

C# side:

    private static extern IntPtr SpecsGetSegmentList();

    public static string Specs_GetSegmentList() {
      return Marshal.PtrToStringAnsi(SpecsGetSegmentList());

C++ side:

  string returnBufferString;  // String, and it's data therefore, must be on the heap so put it here.
  extern "C" __declspec(dllexport) const char* SpecsGetSegmentList() {
    returnBufferString = GlobalWorldSpec->GetSegmentList();
    return returnBufferString.c_str();

Again, thanks for the help!

-- David

David Whatley
Friday, February 14, 2003

*  Recent Topics

*  Fog Creek Home