Han*_*esh 5 c# arrays generics pinvoke unmanaged
我正在C#中实现一个非托管数组类,我需要一些OpenGL调用.
这很好,但我遇到了障碍.以下代码无法编译,我理解为什么,但我怎样才能使它工作?
public T this[int i]
{
get { return *((T*)arrayPtr + i); }
set { *((T*)arrayPtr + i) = value; }
}
Run Code Online (Sandbox Code Playgroud)
我认为如果我确保T是一个结构,它可能会起作用
unsafe class FixedArray<T> where T : struct
Run Code Online (Sandbox Code Playgroud)
也不起作用......
我怎样才能在功能上等同于我上面要做的事情?
编辑:我正在使用Marshal.AllocHGlobal()的非托管数组,以便我的数组被修复,GC不会移动它.当你调用它时,OpenGL实际上并不处理指令,OpenGL将在函数返回后很长时间内尝试访问数组.
如果有帮助,这就是整个班级:
unsafe class FixedArray<T> where T : struct
{
IntPtr arrayPtr;
public T this[int i]
{
get { return *((T*)arrayPtr + i); }
set { *((T*)arrayPtr + i) = value; }
}
public FixedArray(int length)
{
arrayPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)) * length);
}
~FixedArray()
{
Marshal.FreeHGlobal(arrayPtr);
}
}
Run Code Online (Sandbox Code Playgroud)
错误消息是无法获取地址,获取大小,或声明指向托管类型('T')的指针
我很确定无法编译代码.对于你的代码(T*)arrayPtr + i,这将计算arrayPtr + i * 4何时T是a int和arrayPtr + i * 8何时T是a long.由于CLR无法替换4,8或其他任何实际sizeof(T)情况,因此该代码无法正常工作.
您需要做的是用来Marshal为您完成所有工作.编译,但我没有测试它:
unsafe class FixedArray<T> where T : struct
{
IntPtr arrayPtr;
int sizeofT { get { return Marshal.SizeOf(typeof(T)); } }
public T this[int i]
{
get
{
return (T)Marshal.PtrToStructure(arrayPtr + i * sizeofT, typeof(T));
}
set
{
Marshal.StructureToPtr(value, arrayPtr + i * sizeofT, false);
}
}
public FixedArray(int length)
{
arrayPtr = Marshal.AllocHGlobal(sizeofT * length);
}
~FixedArray()
{
Marshal.FreeHGlobal(arrayPtr);
}
}
Run Code Online (Sandbox Code Playgroud)
您不需要非托管数组。
您可以正常声明托管数组:
var myArray = new MyStruct[13];
Run Code Online (Sandbox Code Playgroud)
然后使用该类GCHandle将其固定在内存中并获取其地址:
var handle = GCHandle.Alloc(myArray, GCHandleType.Pinned);
IntPtr address = handle.AddrOfPinnedObject();
Run Code Online (Sandbox Code Playgroud)
该数组将存在于该内存地址,直到您调用handle.Free. 如果您从不调用Free,那么它将一直保留在那里,直到您的程序退出。