为什么我在 c#/c++ 期间收到 System.AccessViolationException dll互操作?

发布于 2025-01-03 03:58:43 字数 922 浏览 1 评论 0原文

我是 C# 和 .NET 新手。我想在 .NET 中使用现有的 C++ dll,因此我正在尝试互操作。我不知道为什么会引发这个异常。我知道该异常意味着什么,我阅读了 MSDN,但不确定为什么会引发该异常。

我的代码是这样的。

dll 代码是一个采用 char* 的简单函数。

extern "C" __declspec(dllexport)void test(char *text)
{
// these raise System.AccessViolationException
// char c = text[0]; 
// int n = strlen(text); 
// char *copy = strdup(text); 
}

C# 代码是一个调用此函数的简单类。

namespace Interop_test
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] text = new char[10];
            for (int i = 0; i < 10; i++)
                text[i] = (char)('A' + i);
            test(text);
        }
        [DllImport("interop_test_dll.dll")]
        private static extern void test(char[] text);
    }
}

如果删除 dll 函数中注释掉的代码,则会引发上述异常。为什么?

如何(或必须)将数据数组从 C# 传递到 C++?

在哪里可以找到有关 C++/C# 互操作期间处理内存管理的更多信息?

I am new to C# and .NET. I want to use my existing C++ dlls within .NET, so I was experimenting with interop. I don't know why this exception is raised. I know what that exception means, I read the MSDN, but not sure why that is raised.

My code is so.

The dll code is a simple function that takes a char*.

extern "C" __declspec(dllexport)void test(char *text)
{
// these raise System.AccessViolationException
// char c = text[0]; 
// int n = strlen(text); 
// char *copy = strdup(text); 
}

The C# code is a simple class calling this function

namespace Interop_test
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] text = new char[10];
            for (int i = 0; i < 10; i++)
                text[i] = (char)('A' + i);
            test(text);
        }
        [DllImport("interop_test_dll.dll")]
        private static extern void test(char[] text);
    }
}

The said exception is raised if the commented out code in the dll function is removed. Why?

How can (or must) I pass an array of data from C# to C++?

Where can I find more information about dealing with memory management during C++/C# interop?

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

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

发布评论

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

评论(4

蓝眼泪 2025-01-10 03:58:43

使用字符串并尝试以下操作:

private static extern void test(ref string text);

如果您想更改测试函数中的字符串,请使用 ref。否则你可以离开它。

Use a string and try this:

private static extern void test(ref string text);

If you want to change your string in your test function then use ref. Otherwise you can leave it.

故乡的云 2025-01-10 03:58:43

在字符串末尾的什么位置放置一个零?我想没有哪里。我不知道这是否是一个问题,但您可以尝试将文本的大小增加到 11,然后在文本 [10] 中添加零。

Where do you put a zero at the end of the string? I think no where. I don't know if that is a problem but you can try increasing the size of of text to 11 and then putting a zero in text[10].

寂寞清仓 2025-01-10 03:58:43

这应该可以解决问题。 CharSet.Ansi 并使用实际的字符串。这些是这里的关键。

namespace Interop_test
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] text = new char[10];
            for (int i = 0; i < 10; i++)
                text[i] = (char)('A' + i);
            test(new string(text));
        }

        [DllImport("interop_test_dll.dll", CharSet = CharSet.Ansi)]
        private static extern void test(
            [MarshalAs(UnmanagedType.LPStr, CharSet = CharSet.Ansi)] string text);
    }
}

This should do the trick. CharSet.Ansi and using an actual string. Those are the keys here.

namespace Interop_test
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] text = new char[10];
            for (int i = 0; i < 10; i++)
                text[i] = (char)('A' + i);
            test(new string(text));
        }

        [DllImport("interop_test_dll.dll", CharSet = CharSet.Ansi)]
        private static extern void test(
            [MarshalAs(UnmanagedType.LPStr, CharSet = CharSet.Ansi)] string text);
    }
}
姐不稀罕 2025-01-10 03:58:43

这些文章不会回答您的具体问题,但当您继续这样做时,它们可能会对您有用。

调用 Win32 dll .NET 与 P/Invoke

值类型的默认编组

另外,在您的dllimport 语句除了指示编组类型之外,还可以添加信息来指示是否应将它们编组为输入或输出或两者。

[DllImport("interop_test_dll.dll")]
private static extern void test([MarshalAs(UnmanagedType.LPStr), In, Out]string text);

These articles won't answer your specific question but they may come in useful to you as you carry on with this.

Calling Win32 dlls in .NET with P/Invoke

Default Marshalling for value types

Also, in your dllimport statements in additional to indicating the marshalling type, you can add information to indicate if they should be marshalled as input or output or both.

[DllImport("interop_test_dll.dll")]
private static extern void test([MarshalAs(UnmanagedType.LPStr), In, Out]string text);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文