2015-02-12 11 views
6

Immaginate ho una funzione chiamataPInvoke con un void * rispetto a una struttura con un'IntPtr

Myfunction(const void * x); 

mio C# dichiarazione potrebbe essere

MyFunction(IntPtr x); 

È questo il punto di vista funzionale e tecnicamente equivalente a

struct MyStruct { IntPtr P; } 

MyFunction(MyStruct x); 

O ci sarà una differenza nel modo in cui vengono smistati.

Sto chiedendo questo perché la libreria che sto chiamando è tutto vuoto *, typedef'd ad altri nomi, e in C# mi piacerebbe ottenere la sicurezza del tipo, per quello che vale.

+1

Questa domanda si riduce a: È una struttura con un singolo membro eseguito il marshalling uguale al tipo di quel membro? Mentre non lo so, * fortemente * sospetto di no. – BradleyDotNET

+0

Non è una risposta diretta, ma in passato ho sempre creato una nuova struttura che avvolge IntPtr (proprio come stai proponendo) chiamata "WhateverPtr" dove "Whatever" è il mio tipo non gestito, e quindi ho usato un marshaller personalizzato usando l'interfaccia ICustomMarshaller https://msdn.microsoft.com/en-us/library/d3cxf9f0(v=vs.90).aspx Quindi non puoi rovinare e confondere i tuoi IntPtrs. È anche più autodocumentante, anche se devi sfornare un po 'di codice boilerplate. Sembra estremamente improbabile che il marshaller sputi magicamente o accetti la tua prova –

risposta

3

Se StructLayout è sequenziale, è effettivamente identico.

Il modo più semplice per verificare questo per te è quello di provarlo, naturalmente:

Fare un progetto C++ DLL Win32:

extern "C" 
{ 
    __declspec(dllexport) void MyFunction(const void* ptr) 
    { 
     // put a breakpoint and inspect 
    } 
} 

fare un progetto C#:

public struct Foo 
    { 
     public IntPtr x; 
    } 

    [DllImport(@"Win32Project1.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl)] 
    public static extern void MyFunctionWithIntPtr(IntPtr x); 

    [DllImport(@"Win32Project1.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl)] 
    public static extern void MyFunctionWithStruct(Foo x); 

    static void Main(string[] args) 
    { 
     IntPtr j = new IntPtr(10); 
     var s = new Foo(); 
     s.x = new IntPtr(10); 
     MyFunctionWithIntPtr(j); 
     MyFunctionWithStruct(s); 
    } 

Nelle tue impostazioni di debug, assicurati di aver selezionato Native debugging abilitato.

Vedrai entrambi i valori come 0xA.

Nota, tuttavia, se si utilizzano i parametri out/ref per IntPtr vs Struct, saranno valori diversi.

+0

e l'errore non provochi nulla. Come fai a sapere che un altro esempio non si comporta diversamente? –

Problemi correlati