| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- using System;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using Urho;
- using Type = System.Type;
- namespace StructsValidator
- {
- class Program
- {
- static string codeContent;
- static void Main(string[] args)
- {
- //get all structs from Urho.dll
- var structs = typeof (UrhoObject).Assembly.GetTypes().Where(t => t.IsValueType && !t.IsPrimitive && !t.IsEnum).ToArray();
-
- // only those with Sequential layout and Sizeof > 1 (not empty)
- var notEmptyStructs = structs.Where(t => !t.IsAutoLayout && Marshal.SizeOf(t) > 1).ToArray();
- bool is64 = IntPtr.Size == 8;
- AppendC("// THIS CODE IS AUTOGENERATED BY SharpieBinder/StructsValidator\n");
- AppendC(is64
- ? "#if defined(_MSC_VER) && (defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)) // generated for x64 only\n"
- : "#if defined(_MSC_VER) && !defined(_WIN64) && !defined(__x86_64__) && !defined(__ppc64__) // generated for x86 only\n");
- AppendC("using namespace Urho3D;\n");
- AppendC("void check_bindings_offsets()\n{");
- foreach (var type in notEmptyStructs)
- AddTest(type);
- AppendC("}");
- AppendC("#endif");
- AppendC($"\n/* Empty structs (stubs?):\n\n {string.Join("\n ", structs.Where(t => Marshal.SizeOf(t) <= 1).Select(t => t.Name).ToArray())}\n\n*/");
- File.WriteAllText("../../../../bindings/Native/asserts_" + (is64 ? "64.h" : "32.h"), codeContent);
- }
- static void AddTest(Type type)
- {
- if (type.FullName.StartsWith("Urho.SharpReality") ||
- type.FullName.StartsWith("Urho.Holo"))
- return;
- var managedName = type.Name;
- var nativeName = ResolveUrhoType(managedName);
- if (nativeName == null)
- return;
- var size = Marshal.SizeOf(type);
- AppendC($"\n\t// {managedName}:");
- AppendC($"\tstatic_assert(sizeof({nativeName}) == {size}, \"{managedName} has wrong size ({size})\");");
- foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
- {
- var managedFieldName = field.Name;
- var nativeFieldName = ResolveUrhoTypeField(managedName, managedFieldName);
- if (string.IsNullOrEmpty(nativeFieldName))
- continue;
- var offset = Marshal.OffsetOf(type, managedFieldName);
- AppendC($"\tstatic_assert(offsetof({nativeName}, {nativeFieldName}) == {offset}, \"{managedName}.{managedFieldName} has wrong offset ({offset})\");");
- }
- }
- static string ResolveUrhoTypeField(string typeName, string fieldName)
- {
- fieldName = fieldName.Trim('_');
- fieldName = char.ToLowerInvariant(fieldName[0]) + fieldName.Substring(1);
- if (fieldName.EndsWith("Ptr")) fieldName = fieldName.Remove(fieldName.Length - 3);
- if (fieldName.EndsWith("Id")) fieldName = fieldName.Remove(fieldName.Length - 2) + "ID";
- if (typeName == "VariantValue") return null; //it's complicated, let's just verify it's sizeof
- if (typeName == "BiasParameters" && fieldName == "slopeScaleBias") return "slopeScaledBias_";
- if (typeName == "AnimationTriggerPoint" && fieldName == "variant") return "data_";
- if (typeName == "CompressedLevel" && fieldName == "imageData") return "data_";
- if (typeName == "CompressedLevel" && fieldName == "rowCount") return "rows_";
- if (typeName == "Matrix3") return fieldName.Replace("C","").Replace("r", "m") + "_";
- if (typeName == "RenderPathCommand" && fieldName.StartsWith("textureName")) return string.Empty;
- if (typeName != "CrowdObstacleAvoidanceParams") fieldName += "_";
- return fieldName;
- }
- static string ResolveUrhoType(string name)
- {
- string[] ignoredTypes = {
- "CustomGeometryVertex",
- "VariantValueLine",
- "BezierConfig",
- "CollisionData",
- "StringHashRef",
- "StringHash",
- "Iterator",
- "AttributeInfo",
- "ProfilerBlock",
- "WeakPtr",
- "VectorBase",
- "Variant",
- "Quaternion",
- "Matrix4",
- "UrhoString",
- "TypeInfo",
- "HashBase",
- "CascadeParameters",
- };
- if (name.EndsWith("EventArgs") ||
- ignoredTypes.Contains(name) ||
- name.Contains("PositionNormal") ||
- //code-generated structs:
- name.Contains("__StaticArrayInitTypeSize") ||
- name.Contains("__FixedBuffer"))
- return null;
- if (name == "UrhoString")
- return "String";
- return name;
- }
- static void AppendC(string line)
- {
- codeContent += line + "\n";
- }
- }
- }
|