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

native C++ dll/C# Problem of memory

本文关键字:内存 问题 C++dll 本机      更新时间:2023-10-16

我有这个错误

其他信息:试图读取或写入受保护的内存。这通常表示其他内存已损坏

你知道为什么吗?我真的被卡住了。。。

我的代码:

本机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());
        }
    }
}

在我的C++代码中,字符串是一个来自string.h的真实字符串。

<string.h>标头中没有名为"string"的类型,只有来自<string>的std::string。pinvoke编组程序无法创建C++对象。您必须使用C字符串:

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

这需要在C#中声明:

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

请注意,字符串转换是有损耗的。您可以使用const-wchar_t*和std::wstring来避免这种情况。

extern"C"void __declspec(dllexport)Mafonc(字符串名称);

诚然,我并没有100%了解extern "C"的确切工作方式,但我敢肯定,你不允许用C++类型来调用它。我假设这是一个std::string,但您没有对其进行名称空间限定

我非常确信,即使您可以在那里使用std::字符串,C#也不会传递std::string。在.NET中,字符串是一种不同类型的对象。因此,您需要一些特殊的编组代码来转换为C++能够理解的类型。

或者,您所称的"C++"实际上是一个C++/CLI应用程序?因为这是不同的东西。

由于ypu在C++中填充字符串,因此必须传递StringBuilder作为参数。我试试这个:

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

那么你确定呼叫约定是正确的吗?不是CallingConvention吗?

不能封送C++std::字符串。有关可以封送的类型,请参阅封送字符串和UnmanagedType。因此,您需要将其封送为UnmanagedType.LPStr或UnmanagedType.LPWStr,并更改非托管DLL。此外,调用约定很可能是Cdecl。把这些放在一起:

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

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

尝试以下操作,

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

你的原生方法在哪里,

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

IJW