原生 C++ dll/C#内存问题

发布于 2024-11-17 10:55:36 字数 1214 浏览 2 评论 0原文

我遇到此错误

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

你知道为什么吗?我真的被困住了...

我的代码:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ゝ杯具 2024-11-24 10:55:36

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

标头中没有名为“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 来避免这种情况。

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.

魂牵梦绕锁你心扉 2024-11-24 10:55:36

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

诚然,我并不是 100% 完全了解 extern "C" 的工作原理,但我很确定您不被允许使用 C++ 类型调用它。我假设这是一个 std::string,但您没有在其上添加名称空间限定。

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

或者您标记为“C++”的内容真的是 C++/CLI 应用程序吗?因为那是不同的东西。

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::strings 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.

御弟哥哥 2024-11-24 10:55:36

由于 ypu 在 C++ 中填充字符串,因此您应该传递 StringBuilder 作为参数。即尝试这样做:

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

那么你确定调用约定是正确的吗?不是 CallingConvention.Cdecl 吗?

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 ?

若水微香 2024-11-24 10:55:36

您无法封送 C++ std::string。请参阅编组字符串UnmanagementType 用于您可以封送的类型。因此,您需要将其编组为 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);

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);
温柔戏命师 2024-11-24 10:55:36

尝试以下操作,

  [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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文