将32位的结构强制转换为64位的结构 [英] struct fornated in 32bits to a struct 64bits
问题描述
大家好,
希望你一切都好吗?
我想与您分享以下问题:
假设我们从以下结构开始,该结构用于保留在以前的32位应用程序中已经实现的设置.
Hello everyone,
I hope you are doing well ?
I would like to share you the following question:
Let''s say we start from the following structure used to persist settings already implemented in a previous 32bits application.
public struct struct32bits
{
[MarshalAs(UnmanagedType.I4)]
public int lVersionNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string szValue;
[MarshalAs(UnmanagedType.R4)]
public float fValue;
}
目的是仍然能够加载以前基于该格式生成的文件,但之后将该结构转换为64位版本.
The objective is to be able to still load the file previously generated based on that format but afterwards convert that structure to a 64bits version.
public struct struct64bits
{
public Int64 lVersionNumber;
public string szValue;
public float fValue;
}
由于对齐问题,我找到了一种循环遍历该结构的字段的方法,但是当我想将值分配给新结构时,总是会遇到转换异常.
Due to alignment issue, I found a way to loop ove the fields of the structure but when I wanted to assign the value into the new structure, I always got convertion exception.
public static bool Migrate32BitsStructTo64BitsStruct(ref struct32bits st32Bits, ref struct64bits st64Bits)
{
System.Reflection.FieldInfo[] OldFields = st32Bits.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
System.Reflection.FieldInfo[] NewFields = st64Bits.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
System.Reflection.FieldInfo OldField = null;
System.Reflection.FieldInfo NewField = null;
for (int i = 0; i < OldFields.Count(); i++)
{
OldField = OldFields[i];
NewField = NewFields[i];
if (NewField != null && OldField != null)
{
object objValue = OldField.GetValue(st32Bits).ToString();
try
{
object objNewValue = Convert.ChangeType(objValue, NewField.FieldType);
NewField.SetValue(st64Bits, objNewValue);
}
catch (Exception ex)
{
}
}
}
return true;
}
我什至尝试使用基于新类型的转换,但是分配异常仍然发生.
如何将32位转换为64位结构?
我什至尝试对结构进行以下修改,但这不能解决问题
I even try with a convertion based on the new type but the assignement exception was still occured.
How would it be possible to apply convertion from 32 to 64 bits structure?
I even tried with the following modification to the structure but this was not solving the issue
public struct struct64bits
{
public Int64 lVersionNumber {get; set;}
public string szValue {get; set;}
public float fValue {get; set;}
}
有人已经尝试过类似的东西吗?
什么意味着要解决该转换问题的64位结构操作?
提前非常感谢您.
最好的问候.
MiQi
Does somebody have already tried something like that ?
What implies the 64bits structure manipulation to solve that convertion issue ?
Thank you very much in advance.
Best regards.
MiQi
推荐答案
我建议您首先手动实现它,以检查转换是否通常会成功.当有了这种概念证明时,如果您喜欢这种方法,则可以使用反射来实现更通用的方法.此类解决方案的问题是确保匹配相应的字段并进行必要的值转换-并且反射太慢了,因此您应该实现一种机制来缓存所有这些FieldInfo(尽管如果您认为性能不那么关键,仅处理几个实例,但这就是另一个故事)
如果您坚持反射机制,这可以为您提供基本的实现思路:
i suggest you implement it by hand at first to check if the conversion would generally succeed. When you have this proof of concept you can implement a more generic way using reflection if you prefer this approach. the problem with such solutions is to make sure you match the corresponding fields and do the neccessary value conversions - and reflection is damn slow, so you should implement a mechanism to cache all those FieldInfos (although the performance can be considered less critical, if you deal with only a couple of instances, but thats another story)
if you keep to the reflection-mechanism, this could provide you with a base implementation idea:
private static IDictionary<string,> _32BitFieldsDict = null;
private static IDictionary<string,> _64BitFieldsDict = null;
private static IDictionary<string,> LoadFieldsFor(Type AIType) {
//does not filter readonly fields
var fieldInfos = AIType.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
var dict = new Dictionary<string,>(fieldInfos.Length);
foreach (var fieldInfo in fieldInfos) {
dict.Add(fieldInfo.Name, fieldInfo);
}
return dict;
}
public static bool Migrate32BitsStructTo64BitsStruct(ref struct32bits st32Bits, ref struct64bits st64Bits) {
if (_32BitFieldsDict == null) //not threadsafe
_32BitFieldsDict = LoadFieldsFor(typeof(struct32bits));
if (_64BitFieldsDict == null) //not threadsafe
_64BitFieldsDict = LoadFieldsFor(typeof(struct64bits));
foreach (var source in _32BitFieldsDict) {
var targetFieldInfo = _64BitFieldsDict[source.Key]; //handle possibility of finding no match
var sourceFieldInfo = source.Value;
var sourceValue =sourceFieldInfo.GetValue(st32Bits).ToString();
var targetValue = Convert.ChangeType(sourceValue, targetFieldInfo.FieldType); //handle conversion problems
targetFieldInfo.SetValue(st64Bits, targetValue);
}
return true;
}
这篇关于将32位的结构强制转换为64位的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!