Ho qualche problema con il marshalling e non riesco a capirlo da solo. Ho cercato questo argomento, ma non avevo ancora avuto fortuna, quindi in pratica sto provando a chiamare una funzione C non gestita dalla mia applicazione C# gestita. La firma della funzione C è simile al seguente:come chiamare una funzione C da C# con un parametro WCHAR * out?
long MyFunction(WCHAR* upn, long upnSize, WCHAR* guid, long* guidSize);
io non l'accesso al file DLL, so solo che la funzione è stata esposta per l'utilizzo e so che cosa si suppone la funzione di fare, ma non so cosa succede all'interno, quindi la funzione riceve un WCHAR * upn che contiene un UserPricipalName e un lungo con la lunghezza del UPN fornito. Viene anche passato un puntatore WCHAR, in cui la funzione scrive un GUID corrispondente che è associato all'UPN passato. Il puntatore guidSize fornisce la dimensione del puntatore, se è troppo piccolo il GUID scritto non è scritto completamente. Se tutto va bene la funzione dovrebbe restituire 0 (non è mai successo ancora, quando viene chiamato da C#)
ora i miei sforzi per invocare e chiamare questo sguardo funzione come questa:
[DllImport(@"MyDll.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern long MyFunction(IntPtr upnPtr, long upnSize, [Out, MarshalAsAttribute(UnmanagedType.LPWStr) ] StringBuilder guidPtr, IntPtr guidSizePtr);
//my attempt to call the Dll's exposed function
string upn = [email protected];
long upnSize = upn.Length;
IntPtr upnPtr = Marshal.StringToHGlobalUni(upn);
IntPtr guidSizePtr = Marshal.AllocHGlobal(sizeof(long));
Marshal.WriteInt32(GuidSizePtr, 128);
var guidSB = new StringBuilder(128);
result = MyFunction(upnPtr, upnSize, guidSB, guidSizePtr);
a seguito ricevo una AccessViolationException. Ho giocato con molte varianti per chiamare la funzione, ma non sono mai riuscito a ricevere uno 0 come valore di ritorno e non sono mai riuscito a leggere il GUID come dovrei fare.
Qualsiasi aiuto con questo sarebbe apprezzato.
Probabilmente è più semplice utilizzare un 'StringBuilder' nella dichiarazione della funzione P/Invoke. –
@CodyGray È già un 'StringBuilder guidPtr'. 'guidPtr' è il parametro di output,' upn' è l'input. – hvd