c# - 使用结构中不安全的固定大小的结构数组使用 C# 访问旧版 C-dll
问题描述
我有一个旧版 C-dll 来访问硬件设备。dll 使用包含结构数组的结构作为函数参数。而且我很难让它与 C# 一起工作(在不安全模式下这没问题,因为这里的访问速度是一个问题)。
旧版 C-dll 的 DeviceDll.h 的原始声明如下所示:
typedef struct tag_RESULT_JUDGEMENT
{
short nJudgementResult;
} struc_RESULT_JUDGEMENT;
typedef struct tag_RESULT_FORMULA
{
float fFormulaResult[3];
float fAnalogResult;
} struc_RESULT_FORMULA;
typedef struct tag_RESULT_SCRIPT
{
short nScriptNo;
float fTime;
short nFormulaCount;
struc_RESULT_FORMULA sFormula[32];
short nJudgementCount;
struc_RESULT_JUDGEMENT sJudgement[8];
} struc_RESULT_SCRIPT;
WORD PASCAL GetResult(LPCTSTR pDeviceCode, struc_RESULT_SCRIPT_NO_LIST* pList, struc_RESULT_SCRIPT* pResult[]);
在 C# 中声明 C-dll 函数的方式如下:
[DllImport("ExternalDevice.dll")]
public unsafe static extern int GetResult(StringBuilder pDeviceCode, struc_RESULT_SCRIPT_NO_LIST* pList, struc_RESULT_SCRIPT **ppResult);
以及我想要访问的结构我以一种不幸的方式声明了一个错误:
[StructLayout(LayoutKind.Explicit)]
public unsafe struct struc_RESULT_SCRIPT {
[FieldOffset(0)]
public Int16 nScriptNo;
[FieldOffset(2)]
public float fTime;
[FieldOffset(6)]
public Int16 iFormulaCount;
[FieldOffset(8)
public fixed struc_RESULT_FORMULA[32] oFormula;
}
错误:固定大小的缓冲区必须是“bool”、“Byte”、. . . 或“双”
有没有办法在结构中声明一个固定结构数组,以便之后我可以使用结构类型变量作为调用旧版 DLL 的参数?
到目前为止我已经尝试过:
避免结构中的结构数组(相当笨拙但有效)
[StructLayout(LayoutKind.Explicit)]
public unsafe struct struc_RESULT_SCRIPT {
[FieldOffset(0)]
public Int16 nScriptNo;
[FieldOffset(2)]
public float fTime;
[FieldOffset(6)]
public Int16 iFormulaCount;
[FieldOffset(8)
public struc_RESULT_FORMULA oFormula01;
[FieldOffset(8 + 16)
public struc_RESULT_FORMULA oFormula02;
. . .
[FieldOffset(8 + 31*16)
public struc_RESULT_FORMULA oFormula32;
}
. . .
struc_RESULT_SCRIPT** ppResult; //local variable => allocated on the stack => so it's already fixed
. . .
int iRv = GetResult(sbMpmIp, &oScriptList, ppResult);
struc_RESULT_FORMULA oFormulaResult = ppResult[0]->oFormula01;
这是可行的——但访问 oFormula01 ... oFormula32 以获取 32 个结构变量是相当笨拙的。我强烈希望将结果作为数组获取,以便我可以像 oFormula = arrayFormula[xx]; 一样访问它 在 for - 循环内。
有没有办法在 C# 的结构中声明一个不安全的固定结构数组 - 或可行的解决方法?
非常感谢您!
解决方案
根据固定大小缓冲区的文档,无法在其中使用结构。
最好的选择似乎与您所做的一样并声明 1..n 字段。对这个相关问题的回答暗示了同样的事情。如果问题只是无法遍历字段,请考虑添加一个迭代器块,例如:
public IEnumerable<struc_RESULT_FORMULA> GetResultFormulas(){
yield return oFormula01;
...
yield return oFormula32;
}
如果您需要随机索引,另一种选择是大型 switch 语句/表达式。
推荐阅读
- django - /savepost/ 处的 MultiValueDictKeyError
- python - 如何将dict项目转换为句子
- c - strcmp 在一个简单的字符串搜索程序中返回 __strcmp_sse2_unaligned()
- sql - 在今天的两个时间之间生成时隙
- postgresql - Postgres JSONB 检索非常慢
- python - RuntimeError:b'在初始化列表中没有参数'(folium)
- java - 数据库架构的最佳方法主要集中在按年和按月同时存储不同字段的数据
- ansible - 如何修复 ansible uri 模块错误有超过 100 个标头?
- android - 有没有办法在进度条中放置分隔线?
- python-3.x - Django网站说“找不到页面(404)”