【问题标题】:Why am I getting System.AccessViolationException during c#/c++ dll interop? [duplicate]为什么在 c#/c++ dll 互操作期间出现 System.AccessViolationException? [复制]
【发布时间】:2012-02-08 10:02:45
【问题描述】:

我是 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++ interop


    【解决方案1】:

    使用字符串试试这个:

    private static extern void test(ref string text);
    

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

    【讨论】:

    • 这适用于此处显示的代码,char c = text[0];但对于 strdup、strlen 等其他操作失败。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我在尝试时收到此错误。 “System.Runtime.InteropServices.MarshalAsAttribute”不包含“CharSet”的定义
      【解决方案4】:

      这些文章不会回答您的具体问题,但它们可能会对您有所帮助。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-15
        • 2020-05-14
        • 2012-04-01
        • 2011-01-22
        相关资源
        最近更新 更多