Domanda

Devo chiamare una dll esterna da c #. Questa è la definizione dell'intestazione:

enum WatchMode { 
   WATCH_MODE_SYSTEM = 0,          
   WATCH_MODE_APPLICATION  = 1 };  

LONG ADS_API WDT_GetMode ( LONG i_hHandle, WatchMode * o_pWatchMode );

Ho aggiunto l'enum e la chiamata in C #:

public enum WatchMode
{
    WATCH_MODE_SYSTEM = 0,
    WATCH_MODE_APPLICATION = 1       
}
[DllImport("AdsWatchdog.dll")]
internal static extern long WDT_GetMode(long hHandle, ref WatchMode watchmode);

Questo genera un AccessViolationException. So che la dll 'funziona' perché ho anche aggiunto una chiamata a GetHandle che restituisce il hHandle menzionato sopra. Ho provato a cambiare il parametro in un int ( ref int watchmode ) ma ottengo lo stesso errore. Qualcuno non sa come posso invocare la chiamata sopra?

È stato utile?

Soluzione

Stai riscontrando una differenza di problema nella dimensione dei parametri tra C # e C ++. Nel mondo C ++ / windows LONG è un numero intero con segno a 4 byte. Nel mondo C # long è un numero intero con segno a 8 byte. Dovresti cambiare la tua firma C # per prendere un int.

ffpf ha torto nel dire che dovresti usare un IntPtr qui. Risolverà questo particolare problema su una macchina a 32 bit poiché IntPtr eseguirà il marshalling come int. Se lo esegui su una macchina a 64 bit, verrà eseguito nuovamente il marshalling come numero intero con segno a 8 byte e andrà in crash.

Altri suggerimenti

Il team di interoperabilità Managed, Native e COM ha rilasciato l'assistente di interoperabilità PInvoke su codeplex. Forse può creare la firma corretta. http://www.codeplex.com/clrinterop/Release/ProjectReleases. aspx? ReleaseId = 14120

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top