Mam trochę problemów z marshalingiem i po prostu nie mogę tego rozwiązać sam. Szukałem tego tematu, ale nie miałem jeszcze szczęścia, więc w zasadzie próbuję wywołać niezarządzaną funkcję C z mojej zarządzanej aplikacji C#. Podpis funkcji C wygląda następująco:jak wywołać funkcję C z C# z parametrem WCHAR * out?
long MyFunction(WCHAR* upn, long upnSize, WCHAR* guid, long* guidSize);
Nie mam dostępu do pliku .dll, ja po prostu wiem, że funkcja jest narażony na wykorzystanie i wiem, co funkcja ma robić, ale nie wiem, co się dzieje w środku, więc funkcja otrzymuje WCHAR * upn z UserPricipalName i long o długości dostarczonego UPN. Również wskaźnik WCHAR jest przekazywany wzdłuż, gdzie funkcja zapisuje z powrotem odpowiedni identyfikator GUID, który jest powiązany z przekazanym UPN. Wskaźnik guidSize dostarcza rozmiar wskaźnika, jeśli jest zbyt mały, zapisany identyfikator GUID nie jest w pełni zapisany. Jeśli wszystko pójdzie dobrze funkcja powinna zwrócić 0 (to nigdy nie zdarzyło się jeszcze, gdy wywołana z C#)
teraz moje wysiłki, aby przywoływać i wywołać tę funkcję wyglądać następująco:
[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);
w wyniku otrzymam AccessViolationException. Grałem z wieloma odmianami, aby wywołać funkcję, ale nigdy nie udało mi się otrzymać wartości 0 jako wartości zwracanej i nigdy nie byłem w stanie odczytać identyfikatora GUID, tak jak powinienem.
Każda pomoc w tym zakresie byłaby doceniana.
Prawdopodobnie najłatwiejszy w użyciu "StringBuilder" w deklaracji funkcji P/Invoke. –
@CodyGray To już 'StringBuilder guidPtr'. 'guidPtr' jest parametrem wyjściowym,' upn' jest wejściem. – hvd