C#:如何设置不安全结构的成员阵列
C#: How to set member arrays of an unsafe struct
我正在使用加载第三方C DLL的VS 2015 MVC C#Web应用程序,我没有源代码。DLL需要一个输入参数。新规格需要几个数组成员。一个是int
数组,另一个是char
数组。
我的C#struct将预期的char
数组定义为byte
,以匹配8位C char:
[StructLayout(LayoutKind.Sequential)]
public unsafe struct MyDLLInput
{
public fixed int SomeList[288];
public fixed byte PathToData[256];
};
结构对我来说似乎是正确的,但是现在我需要设置价值,但我没有任何成功。
MyDLLInput dllInput = new MyDLLInput()
{
SomeList = new int[] {0,12,33,67,93},
PathToData = "C:\some\path\to\data"
}
// Call 3rd Party DLL
MyDLLOutput = MyDLL.EntryPoint(MyDLLInput);
对于两个成员阵列,我都会收到以下错误:
固定尺寸缓冲区只能通过当地人或字段访问。
这里至少有几件事发生 - 除了使用本地我设置值的正确方式外,我还必须将编码从string
转换为byte[]
。
有人可以为我提供一个安装这些值的干净方法的代码示例吗?
是否有某种原因使用不安全的结构?您不能使用编组属性吗?请参阅https://msdn.microsoft.com/en-us/library/eshywdt7(v = vs.110).aspx
无论如何,您需要知道如何从c#字符串转换为字节数组,这取决于编码您的C DLL期望该字符串的内容。例如,在Windows上,通常是"。ANSI代码页",但是在Linux/Unix上,它可能是"当前语言环境"或明确的" UTF-8"。
因此,一个可以使您对编码最大控制的选项是做一些:
[StructLayout(LayoutKind.Sequential)]
public struct MyDllInput
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 288)]
public int[] SomeList;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] PathToData;
}
public static void Main()
{
MyDllInput dllInput = new MyDllInput()
{
SomeList = new int[288],
PathToData = new byte[256]
};
var listData = new int[] { 0, 12, 33, 67, 93 };
Array.Copy(listData, dllInput.SomeList, listData.Length);
var pathToDataBytes = Encoding.UTF8.GetBytes("C:\some\path\to\data");
Array.Copy(pathToDataBytes, dllInput.PathToData, pathToDataBytes.Length);
}
另外,您可以尝试将Pathtodata声明为字符串,然后使用编组属性将其声明为您,而不是直接进行编码转换,然后使用编组属性将其c#c#convent for you;请参阅https://msdn.microsoft.com/en-us/library/s9ts558h(v = vs.110).aspx:
[StructLayout(LayoutKind.Sequential)]
public struct MyDllInput
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 288)]
public int[] SomeList;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =256)]
public String PathToData;
}
public static void Main()
{
MyDllInput dllInput = new MyDllInput()
{
SomeList = new int[288],
PathToData = "C:\some\path\to\data"
};
var listData = new int[] { 0, 12, 33, 67, 93 };
Array.Copy(listData, dllInput.SomeList, listData.Length);
}
在第二种情况下,重要的是,当您声明入口点时,请在dllimportattribute上设置charset属性,以使字符串转换按照所需的方式进行。在您的情况下,您可能想要charset.ansi,因为您的dll拿一个char*而不是wchar_t*。例如,
[DllImport("MyDll.dll", CharSet = CharSet.Ansi)]
private static extern void EntryPoint(ref MyDllInput input);
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 编译器上的策略数据结构不起作用
- 使用具有结构不完整类型错误的模板
- C++/CLI 和 C#/VB 与不安全和外部有什么区别?
- 问:Apache Arrow 数组生成器不安全追加
- 受保护的嵌套结构不能用作派生外部类中的返回类型?
- 不安全的 MPI 非阻塞通信示例?
- 有没有一种简单的方法来检查C++中的不安全表达式
- 具有引用数据成员的结构不是文本类型吗?
- 为什么静态向下转换unique_ptr不安全?
- 使用字节数组具有单字节对齐方式的结构是否安全
- 哪些整数操作不安全
- 结构不继承虚函数
- 为什么这个递归 lambda 函数不安全?
- 解决方法:QPixmap:在GUI线程之外使用pixmap是不安全的
- 正在匹配不安全的正则线程
- C#:如何设置不安全结构的成员阵列
- 适应 C# 中的嵌套不安全结构
- 在哪些体系结构上计算无效指针不安全
- 通过套接字发送和接收原始结构是否不安全