pin_ptr un nativo void * aiuto
-
27-09-2019 - |
Domanda
L'installazione
Ho un API PDF che ha una funzione nativa che viene definito di seguito.
typdef void* PDF_DOCUMENT;
unsigned long PDF_GetMetaText(PDF_DOCUMENT document,
const char tag,
void* buffer,
unsigned long bufferlen)
//Calling it "natively" in C++/CLI function to get the PDF Creator tag
WCHAR result[32];
void* pdoc = PDF_LoadDoc("C:\test.pdf");
int numChars = PDF_GetMetaText(pdoc, "Creator", result, 32);
PDF_CloseDoc(pdoc);
se chiamo il codice di cui sopra nella mia funzione wrapper C ++ / CLI, restituisce la stringa corretta, ma genera un AccessViolationException quando chiamo PDF_CloseDoc. Woops. Ho dimenticato di pin_ptr il puntatore del documento.
Il problema
Quando ho pin_ptr pDoc, posso con successo chiamare queste funzioni native, tuttavia il buffer non contiene più la mia stringa quando ritorna PDF_GetMetaText.
String^ Wrapper::GetCreator(String^ filename)
{
WCHAR buffer[32];
void *pdoc = PDF_LoadDoc(SystemStringToCStr(filename));
pin_ptr<void*> p = &pdoc; //added
int numPages = PDF_GetMetaText(p, "Creator", buffer, 32);
PDF_CloseDocument(p); //doesnt crash, but at this line buffer is an empty string
return gcnew String(buffer);
}
Inoltre ho provato appunta tampone [0] ma che provoca un'eccezione AccessViolation a GetMetaText.
La questione
Non posso dire cosa sta succedendo in GetMetaText, quindi non sono sicuro di quello che è happing a pDoc. Eventuali suggerimenti per il codice di cui sopra?
Soluzione
Questo non ha alcun senso. È possibile aggiungere solo oggetti gestiti, il valore di ritorno di PDF_LoadDoc () certo non apparire come un oggetto gestito da me. Stesso discorso vale per risultato , non è un array<WCHAR>
gestito, solo un semplice vaniglia C array che viene allocato sullo stack frame. Purtroppo, pin_ptr <> non si lamenta di questo.
risultato array può ottenere solo 'vuoto' se il codice viene stomping stack frame. Che è possibile diagnosticare impostando un punto di interruzione di dati sul primo elemento. FWIW, SystemStringToCStr () si presenta come un candidato. Questo non può funzionare senza rilasciare il buffer per la stringa di qualche nativo. Un altro candidato è le dichiarazioni di funzione PDF API. Prestare attenzione al valore del registro ESP e assicurarsi che non cambia. Se lo fa, lo stack è ottenere squilibrata perché non si ha la convenzione di chiamata corretta. Che di solito è __stdcall per le esportazioni DLL.