gpt4 book ai didi

c# - C# 编码期间的 FatalExecutionEngineError

转载 作者:行者123 更新时间:2023-11-30 21:16:03 33 4
gpt4 key购买 nike

我在尝试将许多 DBase IV 文件中的 memofields 中的 C++ 结构读取到 C# (.Net 4) 中,然后将它们插入 MSSQL 2008 中时遇到了问题。数据正在从 DBase 文件中正常提取但我似乎在管理不安全调用方面做错了,因为我随机收到以下错误:

FatalExecutionEngineError was detected
Message: The runtime has encountered a fatal error. The address of the error was
at 0x791fa62c, on thread 0x16c0. The error code is 0xc0000005. This error may be
a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common
sources of this bug include user marshaling errors for COM-interop or PInvoke,
which may corrupt the stack.

下面是我用来读取数据的代码。此代码成功完成并且我从文件中获取的数据是正确的。调用此函数几分钟后,当使用 nhibernate 将对象插入数据库时​​,错误发生(我将其排除在外,因为我认为这对问题来说并不重要)。

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Event
{
public int Number;
public int Month;
public int Day;
public int Year;
public int Hour;
public int Minute;
public int Second;
public UInt32 UPCTime;
public int BlobSize;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = DataLengths.MAX_EVENT_TITLE_LENGTH)]
public string Title;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = DataLengths.MAX_TRIGGER_LENGTH)]
public string Trigger;
}

public struct Trigger
{
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
public string Control;
public int Index;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
public string Mode;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
public string RecordFreq;
public int Pre;
public int Post;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
public string Source;
public int Delay;
public int EventUserNotify;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public int[] Spare;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DataLengths.MAX_EVENT_SENSORS)]
public int[] Sensors;
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Value
{
public Trigger Trigger;
public string[] SensorLabels;
public Point[] Point;
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Point
{
public Single Value;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
public string State;
}

//The dbf is from the java xBasej library that I compiled into a dll using IKVM.net
public Dictionary<Event, Value> Read(DBF dbf)
{
Dictionary<Event, Value> eventData = new Dictionary<Event, Value>();

try
{
for (int i = 1; i <= dbf.getRecordCount(); i++)
{
dbf.gotoRecord(i);
MemoField memofield = (MemoField)dbf.getField("MemoField");

// Perform the conversion from one encoding to the other.
byte[] blob = memofield.getBytes();

if (blob.Length == 0)
{
continue;
}

MemoryStream memoryStream = null;
BinaryReader binaryReader = null;
GCHandle eventHandle = new GCHandle();
GCHandle triggerHandle = new GCHandle();
GCHandle sensorLabelHandle = new GCHandle();
GCHandle pointHandle = new GCHandle();

try
{
memoryStream = new MemoryStream(blob);
binaryReader = new BinaryReader(memoryStream);

//The data was orignally C++ structures so we read the bytes back into C# equivalent
//structures.
int eventDataSize = Marshal.SizeOf(typeof(Event));

eventHandle = GCHandle.Alloc(binaryReader.ReadBytes(eventDataSize), GCHandleType.Pinned);
Event @event = (Event)Marshal.PtrToStructure(eventHandle.AddrOfPinnedObject(), typeof(Event));

//Read the event trigger data
int triggerDataSize = Marshal.SizeOf(typeof(Trigger));
triggerHandle = GCHandle.Alloc(binaryReader.ReadBytes(triggerDataSize), GCHandleType.Pinned);
Trigger trigger = (Trigger)Marshal.PtrToStructure(triggerHandle.AddrOfPinnedObject(), typeof(Trigger));

Value value = new Value();
value.Trigger = trigger;

triggerHandle.Free();

//Read all the sensor labels
List<string> sensorLableList = new List<string>();
for (int sensorIndex = 0; sensorIndex < DataLengths.MAX_EVENT_SENSORS; sensorIndex++)
{
int sensorLableDataSize = DataLengths.MAX_LABEL_LENGTH;
sensorLabelHandle = GCHandle.Alloc(binaryReader.ReadBytes(sensorLableDataSize), GCHandleType.Pinned);
string label = Marshal.PtrToStringAnsi(sensorLabelHandle.AddrOfPinnedObject(), sensorLableDataSize).Trim();
sensorLableList.Add(label);

sensorLabelHandle.Free();
}
value.SensorLabels = sensorLableList.ToArray();
//Read all the recorded sensor data
List<Point> pointList = new List<Point>();
for (int pointIndex = 0; pointIndex < DataLengths.MAX_EVENT_SENSORS; pointIndex++)
{
int pointDataSize = Marshal.SizeOf(typeof(Point));

pointHandle = GCHandle.Alloc(binaryReader.ReadBytes(pointDataSize), GCHandleType.Pinned);
Point point = (Point)Marshal.PtrToStructure(pointHandle.AddrOfPinnedObject(), typeof(Point));
pointList.Add(point);

pointHandle.Free();
}

value.Point = pointList.ToArray();

eventData.Add(@event, value);
eventHandle.Free();
}
finally
{
//Free all the resources used to get the data
if (memoryStream != null) { memoryStream.Close(); }
if (binaryReader != null) { binaryReader.Close(); }
if (eventHandle.IsAllocated) { eventHandle.Free(); }
if (triggerHandle.IsAllocated) { triggerHandle.Free(); }
if (sensorLabelHandle.IsAllocated) { sensorLabelHandle.Free(); }
if (pointHandle.IsAllocated) { pointHandle.Free(); }

GC.Collect();
}
}

}
finally
{
if (dbf != null)
{
dbf.close();
}
}

return eventData;
}

最佳答案

有趣的故障模式,这是不应该发生的。您通常会收到 FEEE,因为垃圾收集堆正在被销毁。这通常很容易解释为一个行为不当的 pinvoked native 函数,该函数执行类似于溢出缓冲区的操作。不过这里没有 pinvoke。

然而,对于这种不幸,有一个极好的候选者:

[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
public string Control;

此编码旨在编码一个 C 字符串,一个以零结尾的字符数组。 A SizeConst = 1 不能按设计正常工作,它只为零终止符留下空间,而不是任何字符。最重要的是,.dbf 文件不包含以零结尾的字符串,根据字段声明,它们是固定宽度的。

访问冲突是否实际上是由编码器错误引起的是一个悬而未决的问题,它可以很容易地在试图找到零终止符时失败。找不到一个并误入未映射的内存页面。

无论如何,你做错了。您必须在结构声明中使用 char[] 而不是字符串,并在 [MarshalAs] 属性中使用 ByValArray。顺便说一句,编码非常痛苦。

关于c# - C# 编码期间的 FatalExecutionEngineError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5437932/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com