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

时间:2012-02-08 10:02:46

标签: c# c++ interop

我是C#和.NET的新手。我想在.NET中使用我现有的C ++ dll,所以我正在尝试使用interop。我不知道为什么会引发这种异常。我知道那个异常意味着什么,我读了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#interop期间处理内存管理的更多信息?

4 个答案:

答案 0 :(得分:0)

使用字符串并尝试:

private static extern void test(ref string text);

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

答案 1 :(得分:0)

你在字符串的末尾把零放在哪里?我觉得没有。我不知道这是否有问题,但你可以尝试将文本的大小增加到11然后在文本中加零[10]。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

Calling Win32 dlls in .NET with P/Invoke

Default Marshalling for value types

此外,在您的dllimport语句中,除了指示编组类型之外,您还可以添加信息以指示它们是否应该作为输入或输出进行编组,或者两者兼而有之。

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