在我的应用程序中,需要使用P / Invoke将绝对任意的对象/结构传递给C ++函数。根据因特网,任何对象都可以作为C ++结构传递(它们在调用期间被固定到特定的存储器位置)。由于我只对数据感兴趣并且不打算调用任何方法,因此这足以满足我的需求。但是,实验表明这些对象必须具有[StructLayout(LayoutKind.Sequential)]
属性,否则代码将无法编译。不幸的是,这些类是由其他开发人员创建的,并不保证具有此属性。
要解决此问题,一种解决方案是将对象传递给特殊的C#包装函数,该函数将:
Type.GetProperties
[StructLayout(LayoutKind.Sequential)]
属性。由于我是C#的新手,我不确定如何动态创建具有任意属性和属性的结构。到目前为止我发现的是MakeGenericType和ExpandoObject,但是需要的是创建一个先前未在任何地方定义的动态结构 - 甚至不是通用对象。有什么想法吗?
答案 0 :(得分:1)
这样的事情能为你效劳吗?
[StructLayout(LayoutKind.Sequential)]
struct MyStruct
{
public int Size;
public IntPtr PtrToArrayOfMetadata;
public IntPtr PtrToArrayOfObjects;
}
public enum Type
{
Int,
Float,
Decimal
}
然后发送一个“动态”对象
Type[] metadata = new Type[2];
metadata[0] = Type.Int;
metadata[1] = Type.Float;
object[] obj = new object[2];
obj[0] = 2;
obj[1]= 1;
GCHandle objHandle = GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection);
IntPtr ptrObj = GCHandle.ToIntPtr(objHandle);
objHandle = GCHandle.Alloc(metadata, GCHandleType.WeakTrackResurrection);
IntPtr ptrMeta = GCHandle.ToIntPtr(objHandle);
MyStruct tmp = new MyStruct();
tmp.Size = 2;
tmp.PtrToArrayOfMetadata = ptrMeta;
tmp.PtrToArrayOfObjects = ptrObj;