c# - 从 C# 访问 C DLL 结构中的数组

标签 c# c arrays dll struct

我正在尝试访问和更改 DLL 中结构中的元素。我遵循了这个关于如何从 DLL 使用 struct 的示例:http://nawatt.com/index.php/corporate/blog/78-using-c-dlls-in-c

我已成功更改非数组变量,但每当我尝试更改数组时,我都会遇到运行时错误。

这是我的 C DLL 代码示例:

    //lib_qrs.dll

    #ifdef __cplusplus
    extern "C" {
    #endif    

    typedef struct TEST_STRUCT
    {   
        unsigned short check[5];

    } test_struct;

    __declspec(dllexport)  void __stdcall test(test_struct *test, unsigned short val){

          // This is an example of what DOES NOT WORK
          test->check[0]=val+1;
          test->check[1]=val+2;
          test->check[2]=val+3;
          test->check[3]=val+4;
          test->check[4]=val+5; 
    }
    #ifdef __cplusplus
    }
    #endif

这是我的 C# 代码示例:

    [StructLayout(LayoutKind.Sequential)]
    public struct TEST_STRUCT
    {   
        public UInt16[] check;

    }

    public class Program
    {
       [DllImport("lib_qrs.dll", EntryPoint="test", CallingConvention = CallingConvention.StdCall)]
        public static extern void test(ref TEST_STRUCT test, int val);
        public TEST_STRUCT testStruct = new TEST_STRUCT();

        static void Main(string[] args)
        {
            testStruct.check=new UInt16[5];
            // WHERE ERROR OCCURS
            test(ref testStruct, 5);
        }
     }

我得到的错误是: *“Test.exe 中发生类型为‘System.AccessViolationException’的未处理异常 附加信息:试图读取或写入 protected 内存。这通常表明其他内存已损坏。”

我知道当我在 C# 中复制我的结构时我必须非常小心内存分配,但我不知道我做错了什么或者我如何解决这个数组问题。 有谁知道我该如何解决这个问题?

最佳答案

该数组的默认编码(marshal)处理是 unsigned short*,而不是 unsigned short[]。您需要应用 [MarshalAs] 属性来将其告知 pinvoke 编码器。修复:

    [StructLayout(LayoutKind.Sequential)]
    public struct TEST_STRUCT {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
        public UInt16[] check;
    }

并且因为您要返回数组中的值,所以您还必须告诉 pinvoke 编码器它需要将数组值复制回来。这需要 [Out] 属性:

    [DllImport("lib_qrs.dll")]
    public static extern void test([Out] ref TEST_STRUCT test, int val);

请注意,如果您只是将参数声明为 ushort[],则两者都不是必需的,假设该结构不包含任何其他字段。

关于c# - 从 C# 访问 C DLL 结构中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22203778/

相关文章:

c# - 为什么我的 List<string> 没有完全写在我的 .CSV 中?

c# - 使用 StreamWriter 构造函数和 File.CreateText 的区别

C填充缓冲区并在达到大小时写出

c# - 如何将 Expander ToggleButton 放在右侧

c# - 转换或简化具有已知值的表达式

c - 如何在 C 中使用另一个结构体内部的结构体(同时使用 malloc 和 2D 数组?)

c - 在 float 变量中排序后数组值发生变化

来自数组中列的 PHP 唯一值

php - 为mysql准备多维数组

arrays - 如何使用 REGEX 按相同的符号序列拆分字符串?