简体   繁体   English

本机C ++ dll / C#内存问题

[英]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++ 原生C ++

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

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

c# 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. 在我的C ++代码中,字符串是来自String.h的真实字符串。

There is no type named "string" in the <string.h> header, only std::string from <string> . <string.h>标头中没有名为“ string”的类型,只有<string> std :: string。 The pinvoke marshaller cannot create C++ objects. pinvoke编组不能创建C ++对象。 You must use a C string: 您必须使用C字符串:

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

Which requires this declaration in C#: 这需要在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. 您可以使用const wchar_t *和std :: wstring来避免这种情况。

extern "C" void __declspec(dllexport) Mafonc(string nom); 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. 诚然,我对extern "C"工作方式还没有100%的了解,但是我敢肯定,您不允许使用C ++类型调用它。 I assume that this is a std::string , but you didn't put the namespace qualification on it. 我假设这是一个std::string ,但是您没有在其上添加名称空间限定。

I'm very certain that, even if you could use a std::string there, C# doesn't pass std::string s around. 非常确定,即使您可以在其中使用std :: string,C#也不会传递std::string In .NET, strings are a different kind of object. 在.NET中,字符串是另一种对象。 So you would need some special marshalling code to do the conversion to a type that C++ understands. 因此,您需要一些特殊的编组代码才能转换为C ++可以理解的类型。

Or is what you label as "C++" really a C++/CLI application? 还是您标记为“ C ++”的真的是C ++ / CLI应用程序? Because that's something different. 因为那是不同的。

Since ypu are populating the string in C++, you sould pass a StringBuilder as a parameter. 由于ypu在C ++中填充字符串,因此您可以将StringBuilder作为参数传递。 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 ? 不是CallingConvention.Cdecl吗?

You cannot marshal a C++ std::string. 您无法封送C ++ std :: string。 See marshalling strings and UnmanagedType for the types you can marshal. 有关可封送的类型,请参见封送字符串UnmanagedType So you need to marshal it as an UnmanagedType.LPStr or UnmanagedType.LPWStr, and change your unmanaged DLL. 因此,您需要将其作为UnmanagedType.LPStr或UnmanagedType.LPWStr封送,并更改您的非托管DLL。 Additionally, the calling convention most probably is Cdecl. 此外,调用约定很可能是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 IJW

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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