none
Passing StringBuilder from C# to C++ inside VB Forms Application RRS feed

  • Question

  • Hi,

    Scenario :

    I have hosted CLR in a VB Forms application process . Now I need to pass string from manged code to a native dll which modifies the content of it and then returns back the modified string. As per MSDN we can achieve that by passing StringBuilder object from managed to unmanaged code, but when I try to change the contents of the StringBuilder object in unmanaged code I get an exception :

    "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

    The code which I'm trying to run is shown below. One more thing the same code works fine if I try the same inside a Power Builder Application.

    Managed Code : C# dll

            [DllImport("native.dll", EntryPoint="TestUsingStringBuilder", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall )]
            public static extern bool TestUsingStringBuilder(System.Text.StringBuilder className,int nMaxCount);

    void Method()
    {

                    System.Text.StringBuilder buff = new System.Text.StringBuilder(256);
                    bool bRet = TestUsingStringBuilder(buff,buff.MaxCapacity + 1);
    }

    Native Code : c++ dll

    extern "C" __declspec(dllexport) BOOL TestUsingStringBuilder(LPSTR lpstrClsName, int maxLen)
    {   
            CTracer::debugTrace(TEXT(" TestUsingStringBuilder "));
            strcpy(lpstrClsName,"INITIALIZE");//Exception: Attempted to read or write protected memory.
            return TRUE;
    }


    any help would be highly appreciated.

    Thanks,
    WPFLearner
    Friday, August 28, 2009 10:00 AM

Answers

  • The calling convention is wrong, you forgot __stdcall in the C++ code.  You are also passing the wrong size, it is buff.Capacity (not +1).  And of course, you'd better use it.

    Hans Passant.
    Friday, August 28, 2009 10:35 AM
    Moderator

All replies

  • The calling convention is wrong, you forgot __stdcall in the C++ code.  You are also passing the wrong size, it is buff.Capacity (not +1).  And of course, you'd better use it.

    Hans Passant.
    Friday, August 28, 2009 10:35 AM
    Moderator
  • Thank you, Hans, for the excellent suggestions. I’d like to add two:

     

    1. On the native side, it’s recommended to use strcpy_s instead of strcpy to copy the string.

    strcpy_s(lpstrClsName, maxLen,"INITIALIZE”)

    It avoids the buffer-overrun security hole.

     

    2. A very useful skill to debug this kind of interop issue in Visual Studio is to enable unmanaged code debugging, and step from .NET code into C++ code and check the parameter values. To enable unmanaged code debugging in your .NET project, you can open the project setting and turn to the Debug tab, then check the “Enable undamaged code debugging” option. Additionally, in VS Tools/Options, switch to the Debugging node, and uncheck the “Enable Just My Code (Managed only)” option in the General tab.

     

    Thanks,

    Jialiang Ge

    MSDN Subscriber Support in Forum

    If you have any feedback of our support, please contact msdnmg@microsoft.com.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, August 31, 2009 9:32 AM
    Moderator
  • Hello WPFLearner

    I'm writing to check the status of the issue on your side. Were the suggestions from Hans and me helpful to you? If you have any other quesions or concerns, please feel free to post here.

    Thanks,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, September 4, 2009 9:26 AM
    Moderator