为什么我在 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# 互操作期间处理内存管理的详细信息?
使用字符串并尝试以下操作:
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);