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

本文关键字:AccessViolationException System 互操作 dll c++ 为什么 | 更新日期: 2023-09-27 18:23:39

我是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# 互操作期间处理内存管理的详细信息?

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

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

private static extern void test(ref string text);

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

你在字符串末尾放零的什么地方?我认为没有地方。我不知道这是否是一个问题,但您可以尝试将文本的大小增加到 11,然后在文本中输入零[10]。

这应该可以解决问题。 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);
    }
}

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

使用 P/Invoke 在 .NET 中调用 Win32 dlls

值类型的默认封送处理

此外,在 dllimport 语句中,除了指示封送类型之外,还可以添加信息以指示它们是否应封送为输入或输出,或同时作为两者。

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