gpt4 book ai didi

c# - 根据字符串中定义的数据类型在运行时生成结构

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

如何在运行时从字符串中定义的一系列类型生成结构?

我有一个标题,例如包含“float, float, byte[255]”。我有跟在这个标题后面的二进制数据,并保持数据的顺序。在运行时读取 header 之前,我不知道数据类型,并且我想生成一个结构,我可以使用该结构将二进制数据编码为结构数组。

有什么想法吗?

最佳答案

显然您知道您的应用程序的要求是什么,但正如 lejon 所说,问题是在创建结构后如何访问它。在 c# 中,您将不得不跳过箍,而不是在不需要显式声明类型的 vb 中。

我可以想出几种方法来完成你想要的。您可以使用 CodeDom 生成您的代码,请参阅 http://www.15seconds.com/issue/020917.htm

就个人而言,对于一个简单的结构,我会手动构建代码

  string szCode =@"using System;
using System.Windows.Forms;

namespace RunTimeCompile
{
[StructLayoutAttribute(LayoutKind.Sequential)]
public string MyStruct
{"

然后,对于头文件中的每种数据类型,将成员附加到 szCode 字符串。 (您需要构建一个基本函数来解析您的类型):

szCode += "float Field1;\n"; 
szCode += "float Field2;\n";
szCode += "byte[255] Field3;\n";

然后关闭你的代码...

szeCode+=";\n;\n";

现在您已经有了源代码,请使用 CodeDom 对其进行编译。

oCodeDomProvider = CodeDomProvider.CreateProvider("CSharp");
// Add what referenced assemblies
CompilerParameters oCompilerParameters = new CompilerParameters();
oCompilerParameters.ReferencedAssemblies.Add("system.dll");
// set the compiler to create a DLL
oCompilerParameters.GenerateExecutable = false;
// set the dll to be created in memory and not on the hard drive
oCompilerParameters.GenerateInMemory = true;
oCompilerResults =
oCodeDomProvider.CompileAssemblyFromSource(oCompilerParameters, szCode);

注意:您还可以使用 CompileAssemblyFromFile 从文件而不是内存中的源代码进行编译

现在在继续检查之前没有编译错误

if (oCompilerResults.Errors.Count!=0) return; // add you own error handling

现在您可以像这样检索动态生成的结构的实例

oAssembly = oCompilerResults.CompiledAssembly;
oObject = oAssembly.CreateInstance("RunTimeCompile.MyStruct");
oType = oObject.GetType();

现在您可以读取二进制文件的所有行,并使用 Marshal 或您想要序列化二进制数据的任何其他方法(也许是二进制序列化器)将它们编码到 MyStruct[] 的数组中。

例如使用 Runtime.Interop.Marshal 你可以做这样的事情(你需要稍微摆弄一下,特别是你不能在你的代码中声明 MyStruct[] 所以你需要做一些像 oObjectArray = oAssembly.CreateInstance("RunTimeCompile.MyStruct[]") 声明 destValues 结果数组:

byte[] sourceData = ReadSourceData(); // TODO: generate method to load your BLOB
MyStruct[] destValues = new MyStruct[Marshal.SizeOf(oType) + 1]
int arrayIndex = 0;

GCHandle handle = GCHandle.Alloc(sourceData, GCHandleType.Pinned);
try
{
IntPtr buffer = handle.AddrOfPinnedObject();
buffer = (IntPtr)(buffer.ToInt32() +
(arrayIndex*Marshal.SizeOf(typeof(MyStruct))));
destStruct = (MyStruct)Marshal.PtrToStructure(buffer, typeof(MyStruct));
}
finally
{
handle.Free();
}

return MyStruct;

现在你有了结构数组。

关于c# - 根据字符串中定义的数据类型在运行时生成结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4991990/

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