none
Strings with PInvoke

    Question

  • I am receiving a 'Attempted to read or write protected memory. This is often an indication that other memory is corrupted.' error when using a PInvoke call. Below is the Visual C++ and C# code. I have tried using StringBuilder and String return types as well as passing a StringBuilder to the C++ but cannot get this to work correctly. This is an urgent matter so any help will be greatly appreciated.

    C++

    std:Tongue Tiedtring GetAString()
    {
        std:Tongue Tiedtring myString;
        myString = "Here is a return value";
        return myString;
    }


    C#
    [DllImport("myCppDll.dll", CharSet=CharSet.Auto)]
    private static extern StringBuilder GetAString();

    static void Main(string[] args)
    {
        StringBuilder myBuilder = GetAString();
        Console.WriteLine(myBuilder.ToString());
    }
    Friday, June 08, 2007 6:09 PM

Answers

  • Try the following:

    stdTongue Tiedtring GetAString()
    {
        stdTongue Tiedtring myString;
        myString = "Here is a return value";
        return myString;
    }


    C#

    using System.Runtime.InteropServices;
    [DllImport("myCppDll.dll", CharSet=CharSet.Auto)]
    private static extern IntPtr GetAString();

    static void Main(string[] args)
    {
        IntPtr stringPtr  = GetAString();
        string myString = Marshall.PtrToStringAuto(stringPtr);
        Console.WriteLine(myString);
    }

    Saturday, June 09, 2007 1:49 AM
  • Hi Anonymous280z,

      I don't think it's a good idea to export a function which directly returns a class type in a dll for non-c++ use.

      I suggest you to write another DLL to convert the std:Tongue Tiedtring to char * using string.c_str(). Of directly expose string.c_str() to C# program in another function.

      And then use this DLL in your C# program, you can consequently use Marshal.PtrToStringAuto() to extract the string.

      Hope this can help you!

    Thanks!

    Wednesday, June 13, 2007 5:59 AM
  • Please note, in the C++ code, the string is allocated in Read-Only buffer.

     

    the code like :

     

    str="abcd";

     

    The "abcd"'s type is const char *, which means it is read only.

     

    however, in C#, the stringbuilder maintains Read-Write buffer. I behelive this is the root cause.

     

    Please try the following code in C++ instead:

     

    std:Tongue Tiedtring str;

    size_t len=strlen("your string");

    char *p=new char[len+1];

    strcpy(p,"your string");

    str=p;

    return str;

    Wednesday, June 13, 2007 8:07 AM

All replies

  • Try the following:

    stdTongue Tiedtring GetAString()
    {
        stdTongue Tiedtring myString;
        myString = "Here is a return value";
        return myString;
    }


    C#

    using System.Runtime.InteropServices;
    [DllImport("myCppDll.dll", CharSet=CharSet.Auto)]
    private static extern IntPtr GetAString();

    static void Main(string[] args)
    {
        IntPtr stringPtr  = GetAString();
        string myString = Marshall.PtrToStringAuto(stringPtr);
        Console.WriteLine(myString);
    }

    Saturday, June 09, 2007 1:49 AM
  • Using this example causes the application to go into lala land. The next line (in this example the Console.Write) is not hit and there isn't an exception thrown but the console application just closes.

    Theoretically this seems like the right way to go. When doing the reverse in C++ converting the text, like the example below, I get the expected result but for some reason this text conversion using PInvoke is not working on the C# side. Thanks for your help and if you have any further ideas I greatly appreciate the input.

    char* str = (char*)System::Runtime::InteropServices::Marshal:Tongue TiedtringToHGlobalAnsi(inputString).ToPointer();

    Monday, June 11, 2007 2:14 PM
  • Hi Anonymous280z,

      I don't think it's a good idea to export a function which directly returns a class type in a dll for non-c++ use.

      I suggest you to write another DLL to convert the std:Tongue Tiedtring to char * using string.c_str(). Of directly expose string.c_str() to C# program in another function.

      And then use this DLL in your C# program, you can consequently use Marshal.PtrToStringAuto() to extract the string.

      Hope this can help you!

    Thanks!

    Wednesday, June 13, 2007 5:59 AM
  • Please note, in the C++ code, the string is allocated in Read-Only buffer.

     

    the code like :

     

    str="abcd";

     

    The "abcd"'s type is const char *, which means it is read only.

     

    however, in C#, the stringbuilder maintains Read-Write buffer. I behelive this is the root cause.

     

    Please try the following code in C++ instead:

     

    std:Tongue Tiedtring str;

    size_t len=strlen("your string");

    char *p=new char[len+1];

    strcpy(p,"your string");

    str=p;

    return str;

    Wednesday, June 13, 2007 8:07 AM
  • Converting to a char looks to be the way to go. I am able to grab strings this way. Thanks to all who took the time to help me out!
    Tuesday, June 19, 2007 1:29 PM