简体   繁体   中英

Passing a string from C# to a c++ .dll is scrambling the data

I have a c++ dll, with this code:

extern "C"
{
    const char *SaveDate;

    __declspec(dllexport) void SetDate(const char *date)
    {
        SaveDate = date;

        std::cout << "date: " << SaveDate  << std::endl;

    }
}

When i print the value inside that function, it prints

'date: 20160215' 

But when I grab the 'SaveDate' variable from another function, and print it, it prints

'104'

My C# is:

[DllImport("XmlRecord.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetSlate(string date);


public bool SetupRec()
{
    string Date = DateTime.Now.ToString("yyyyMMdd");
    SetSlate(Date);
}

Why is this value being scrambled in the c++ dll?

Thank you.

If you use P/Invoke, any argument passed to your C function will be valid for the duration of the call .

If you want to reuse the input string, you need to copy it. The one you got as argument will be freed after the call (and you don't even know when ). Just save it to a std::string instead of holding a const char * .

If you absolutely want to avoid copying the data, there are mechanisms you could leverage, but you'll have to take the appropriate precautions on the C# side, as the GC is allowed to move objects in memory at any time.
This involves long-term object pinning (with the GCHandle class), which is a hindrance to the GC, so it's best avoided. Short-term pinning (with the fixed statement) is doable if you can limit the data validity to a single stack frame. You'll then have to pass your data as an IntPtr to the C function, to bypass the .NET marshaling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM