我如何堆分配代表并获得指向它的指针?
我希望能够将其强制转换为void指针并返回,以便可以将其存储在异构数组中。
delegate
]是具有2个指针字段的简单结构。它具有以下字段:.ptr
,它是上下文指针(this
引用,闭包,堆栈帧指针).funcptr
,它是函数指针this
引用上,这通常是类的成员函数),则可以存储一个使用这2个void*
值在堆上构造struct或复制其字节,然后将其反序列化回委托。示例:
alias MyDelegate = void delegate();
void main()
{
int local;
MyDelegate dlg = () { import std.stdio; writeln("delegate ", local); };
// T.sizeof always gives the size of what the size is as a struct.
// So not the size of what something points to (e.g. class is size_t.sizeof)
// Copies the bytes on the stack stored for the delegate, doesn't pin the
// context pointer or anything like that which would make it a safer operation
auto heap = (cast(ubyte*)&dlg)[0 .. MyDelegate.sizeof].dup.ptr;
local = 5;
callHeapDlg(heap);
}
void callHeapDlg(ubyte* heap)
{
// This could be a potentially unsafe cast if casting to some other delegate!
// You might be casting away safety attributes or other things. Best to
// restrict the type of the delegate you convert to heap from the start.
// Simply recreates the delegate by casting a pointer to the bytes you have
// copied to a pointer to a delegate object and then dereferencing it.
// This copies the pointers from the heap back to the stack here.
auto dlg = *(cast(MyDelegate*) heap[0 .. MyDelegate.sizeof]);
dlg(); // prints "delegate 5"
}
但是请永远不要忘记这是一个不安全的操作,您可能会破坏应用程序,甚至不小心引入任意代码执行。特别是如果您的委托上下文指针超出范围并被释放,则可能会遇到严重的不可调试问题。例如,在这种情况下,您不应在主函数之外调用分配给堆的委托,因为它很可能包含指向主函数当前堆栈框架的指针,该指针在离开后将变为无效。