Supponiamo che tu stia chiamando una funzione Win32 che riempirà il tuo array di byte. Si crea una matrice di dimensione 32, vuota. Quindi passarlo alla funzione Win32 da riempire int e utilizzarla successivamente nel codice gestito. Esiste la possibilità che l'array di byte possa essere spostato o sovrascritto tra il momento in cui è stato allocato e compilato dalla funzione Win32?Quando si passa un array byte [] gestito tramite PInvoke per essere compilato da Win32, deve essere bloccato?
risposta
Risposta breve: No, pinning non è necessario in questo caso
Longer Risposta:
Il CLR Inchioderò automaticamente i riferimenti a oggetti gestiti quando l'attraversare il confine PInvoke. Non appena la funzione PInvoke viene chiusa, il riferimento verrà sbloccato. Quindi in situazioni come avere una funzione nativa riempire uno byte[]
non è necessario bloccare manualmente perché l'oggetto è utilizzato solo dal codice nativo durante la chiamata di funzione.
Il blocco manuale della matrice diventa necessario se il codice nativo memorizza nella cache il puntatore gestito. Quando ciò accade, devi pin manualmente l'array fino a quando il codice nativo non ha più bisogno del puntatore. In questo caso presumo il puntatore non è memorizzato quindi non è necessario pin
Riferimento - http://msdn.microsoft.com/en-us/magazine/cc163910.aspx#S2
Mi spiace rispondere alla mia domanda, ma credo che se il tipo è blittabile, poiché byte [] è, allora l'array verrebbe bloccato durante il marshalling dal runtime, quindi non sarebbe necessario alcun pinning. Un oggetto nell'altro tempo sarebbe diverso. Per favore correggimi se sbaglio.
Qual è il modo migliore per bloccare un byte [] in C#? –
Pin un byte [] usando la parola chiave 'fixed' all'interno di un blocco di codice' non sicuro'. Vedi http://msdn.microsoft.com/en-us/library/f58wzh21(VS.71).aspx –
@Reed: Penso che sia proprio qui. Il codice del marshaller pinerà l'array durante la chiamata da managaged a nativo, quindi l'array dovrà essere pinned esplicitamente solo se si desidera fare riferimento nel codice nativo in un altro momento. –
secondo MSDN Marshaling Arrays of Types solamente un array passato per riferimento può essere scritto dal codice non gestito. Quindi sembra che tu devi dichiarare il parametro array [out] o [in, out] se vuoi riempirlo sul lato non gestito.
Questa pagina http://msdn.microsoft.com/en-us/library/aa719896(VS.71).aspx riesce ad andare avanti e avanti senza mai dire esplicitamente che il marshaller attacca gli array durante la chiamata da gestito a non gestito, ma gran parte di ciò che descrive non funzionerebbe se il marshaller non avesse pin.
- 1. Quando deve essere usato assert()?
- 2. L'oggetto JSON deve essere str, non 'byte'
- 3. Quando deve essere utilizzato WS_EX_NOREDIRECTIONBITMAP?
- 4. Quando deve essere chiamato super.onResume()?
- 5. Quando deve essere rimosso removeStickyEvent (...)?
- 6. Quando un riferimento deve essere atomico?
- 7. Quando deve essere eliminato un oggetto ManualResetEvent?
- 8. Il seguente programma deve essere compilato secondo lo standard?
- 9. Blocco di ottava quando deve essere tracciato
- 10. Cosa significa LPCWSTR e come deve essere gestito?
- 11. Symfony 2 - Entità deve essere gestito o in programma per la rimozione di un singolo calcolo
- 12. Connessione da albero precedente deve essere simmetrica
- 13. Quando JavaScript NON deve essere gzip?
- 14. javac può essere compilato da stdin?
- 15. ScheduledExecutorService: quando deve essere richiamato l'arresto?
- 16. ReactJS: Quando deve essere impostato setState da isMounted?
- 17. Ogni BeginInvoke deve essere seguito da EndInvoke?
- 18. Il controllo 'sembra' essere bloccato
- 19. Quando dovrebbe essere usato un memoryview?
- 20. Un array PHP deve essere dichiarato prima dell'uso?
- 21. Web deve essere installato
- 22. Come leggere da un os.pipe() senza essere bloccato?
- 23. TypeError: deve essere stringa senza byte nulli, non str
- 24. Potrebbe essere compilato Python per l'esecuzione sul motore V8?
- 25. Debug di un componente gestito da C++ Win32
- 26. SQL: Perché un CREATE TRIGGER deve essere preceduto da GO
- 27. setProperty deve essere sovrascritto da tutte le sottoclassi di SOAPMessage
- 28. Questo codice deve essere in un documento.ready?
- 29. CFBundleVersion deve essere un elenco separato da un periodo
- 30. Perché la funzione defaultWriteObject deve essere chiamata per prima quando si scrive in un ObjectOutputStream?
Ok, quindi la domanda è cosa succede quando la chiamata Win32 non ritorna immediatamente? Supponiamo ad esempio una chiamata a ReadFile() che utilizza I/O sovrapposti e un evento di reset manuale? La chiamata ritorna immediatamente, mentre viene eseguita l'operazione di I/O. In questo caso, l'array di byte deve essere bloccato? Come si può sapere se la libreria nativa sta memorizzando nella cache la matrice –
Beh, dovrei aver letto prima il collegamento perché fornisce ReadFileEx e I/O sovrapposti come esempio di quando è necessario eseguire il pin. –