将32位的结构强制转换为64位的结构 [英] struct fornated in 32bits to a struct 64bits

查看:55
本文介绍了将32位的结构强制转换为64位的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

希望你一切都好吗?

我想与您分享以下问题:

假设我们从以下结构开始,该结构用于保留在以前的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆