简体   繁体   中英

native C++ dll/C# Problem of memory

I have this error

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

Do you know why? I am realy stuck...

My Code :

Native c++

    extern "C" void __declspec(dllexport) Mafonc(string nom);

void __declspec(dllexport) Mafonc(string nom)
{
    string tom = nom;
}

c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

using System.Runtime.InteropServices;
using System.Security;

namespace TradeInterface
{
    static class Program
    {
        [DllImport("TradeEngine.dll", CharSet = CharSet.Ansi,
            CallingConvention = CallingConvention.StdCall,
            ExactSpelling = true),
        SuppressUnmanagedCodeSecurity]
        public static extern void Mafonc(string nom);

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Mafonc("E:\\DossierProjet");

            Application.Run(new Form1());
        }
    }
}

in my C++ code the string is a real string coming from String.h.

There is no type named "string" in the <string.h> header, only std::string from <string> . The pinvoke marshaller cannot create C++ objects. You must use a C string:

extern "C" __declspec(dllexport)
void Mafonc(const char* nom)
{
    std::string tom(nom);
}

Which requires this declaration in C#:

    [DllImport("TradeEngine.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern void Mafonc(string nom);

Note that the string conversion is lossy. You can use const wchar_t* and std::wstring to avoid that.

extern "C" void __declspec(dllexport) Mafonc(string nom);

Admittedly, I'm not 100% up on exactly how extern "C" works, but I'm pretty sure you're not allowed to call it with a C++ type. I assume that this is a std::string , but you didn't put the namespace qualification on it.

I'm very certain that, even if you could use a std::string there, C# doesn't pass std::string s around. In .NET, strings are a different kind of object. So you would need some special marshalling code to do the conversion to a type that C++ understands.

Or is what you label as "C++" really a C++/CLI application? Because that's something different.

Since ypu are populating the string in C++, you sould pass a StringBuilder as a parameter. Ie try with this:

[DllImport("TradeEngine.dll", CharSet = CharSet.Ansi,
            CallingConvention = CallingConvention.StdCall,
            ExactSpelling = true),
        SuppressUnmanagedCodeSecurity]
        public static extern void Mafonc(StringBuilder nom);

Then are you sure the calling convention is correct ? Isn't CallingConvention.Cdecl ?

You cannot marshal a C++ std::string. See marshalling strings and UnmanagedType for the types you can marshal. So you need to marshal it as an UnmanagedType.LPStr or UnmanagedType.LPWStr, and change your unmanaged DLL. Additionally, the calling convention most probably is Cdecl. Putting this together:

void __declspec(dllexport) Mafonc(LPSTR nom)
{
    // Do something with nom
}

and

[DllImport(
    "TradeEngine.dll",
    CharSet = CharSet.Ansi,
    CallingConvention = CallingConvention.Cdecl,
    ExactSpelling = true),
    SuppressUnmanagedCodeSecurity]
public static extern void Mafonc([MarshalAs(UnmanagedType.LPStr)]string nom);

Try following,

  [DllImport("TradeEngine.dll",CallingConvention = CallingConvention.Cdecl)]
            private static  extern void Mafonc(StringBuilder data);

Where your native method is,

extern "C" _declspec(dllexport) void Mafonc(std::string data)
{
    string xyz=data;

}

IJW

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