我正在尝试访问和更改 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/