Io ho un metodo con la firmaCome ottenere un IntPtr in una struct?
public int Copy(Texture texture, Rect? srcrect, Rect? dstrect)
Rect
è una struttura, ma ho bisogno di consentire al chiamante di passare null
(o IntPtr.Zero
) al metodo pure.
Voglio poi farlo passare a una DLL con la firma
[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")]
internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, IntPtr srcrect, IntPtr dstrect);
speravo avrei potuto fare qualcosa di simile al seguente:
return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? (IntPtr)srcrect.Value : IntPtr.Zero, dstrect.HasValue ? (IntPtr)dstrect.Value : IntPtr.Zero);
Ma non riesco a lanciare lo struct come quello. C'è un altro modo in cui posso ottenere un IntPtr
?
Ci
alternativa è quella di creare 4 sovraccarichi:
ref Rect, ref Rect
IntPtr, IntPtr
ref Rect, IntPtr
IntPtr, ref Rect
che potrebbe ottenere anche più caotico se ho mai bisogno di passare più di 2 puntatori di struttura.
mi si avvicinò con una soluzione, ma ho alcune domande su di esso:
public int Copy(Texture texture, Rect? srcrect=null, Rect? dstrect=null)
{
return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? StructToPtr(srcrect) : IntPtr.Zero, dstrect.HasValue ? StructToPtr(dstrect) : IntPtr.Zero);
}
private static IntPtr StructToPtr(object obj)
{
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
Marshal.StructureToPtr(obj, ptr, false);
return ptr;
}
se avessi usato ref Rect
non avrei dovuto allocare memoria per la struct - cosa fare diversamente da questo?
Ho fatto qualche sperimentazione. La soluzione ref Rect
corre più o meno alla stessa velocità di conversione di una generando un Rect
a un IntPtr
IntPtr
per un Rect
, che mi porta a sospettare che C# sta facendo qualcosa di molto simile sotto il cofano quando si utilizza rif. Non appena eseguo il comando Rect?
e aggiungo la logica condizionale al metodo che esegue fino al 50% più lento ... quindi il percorso a 4 sovraccarichi sarebbe probabilmente il più veloce. Tuttavia, stiamo parlando di 100-150 ms per 100.000 iterazioni, il che significa che il metodo stesso è super economico, il che probabilmente è il motivo per cui i condizionali hanno un impatto così notevole. In quanto tale, mi sto attenendo alla mia soluzione personalizzata StructToPtr
in quanto è la soluzione più semplice.
Il tuo titolo non è valido. Non è possibile convertire una struttura in un IntPtr. È possibile, tuttavia, ottenere un puntatore a una struttura. –
@ JimMischel: vero. Non stavo pensando di "convertirlo" realmente, stavo pensando a qualcosa sulla falsariga di un cast; in C puoi schiaffeggiare un '&' prima di una variabile per ottenere il suo indirizzo. – mpen