funkcji DLL w C wygląda następująco:Wywołanie znaku * w C DLL obsługiwane jako ciąg w języku C#. Problem ze znakami NUL
int my_Funct(char* input, char* output);
Muszę zadzwonić to od C# aplikacji. Zrobić to w następujący sposób:
...DllImport stuff...
public static extern int my_Funct(string input, string output);
Ciąg wejściowy jest doskonale przekazane do biblioteki DLL (mam widoczny dowód tego). Wynik działania funkcji wypełnia się, mimo że jest błędny. Mam dane hexa w nim, jak:
3F-D9-00-01
ale niestety wszystko, co jest po dwóch zer jest cięty, a tylko dwa pierwsze bajty przyjść do mojego C# aplikacji. Zdarza się, ponieważ (jak sądzę) traktuje jako znak null i przyjmuje go jako koniec ciągu.
Każdy pomysł, jak mogę się go pozbyć? Próbowałem go określić jako IntPtr zamiast ciąg, ale nie wiem, co z nim zrobić później. że próbował wykonać po:
byte[] b1 = new byte[2];
Marshal.Copy(output,b1,0,2);
2 powinna być zwykle długość tablicy bajtów. Ale dostaję wszelkiego rodzaju błędy: jak "Żądany zakres rozciąga się poza koniec tablicy." lub "Próba odczytu lub zapisu chronionej pamięci ..."
Doceniam każdą pomoc.
(1) Ciągi C# są szersze niż char; mają szerokość 2 char zamiast 1. (2) Wartość char * zwracana przez tę funkcję nie będzie miała wymaganej dodatkowej struktury, która będzie poprawnym łańcuchem C# (nawet jeśli ma właściwą szerokość). –
Musisz przeczytać na temat COM Interop i P/Invoke, aby dowiedzieć się, jak wykonać to działanie. Zrób to i oddzwoń, jeśli masz pytania na temat tego materiału. –
Urządzenie pinvoke marshaller obsługuje tylko ciągi C. Oczywiście nie jest ciągiem C, gdy ma bajty, które mają znaczenie po 0. Jest to bajt []. Ale przy znaczącym rozłączeniu się nikt nie może zrozumieć, jak * wiele * bajtów jest istotnych. Ta funkcja jest bardzo trudna w użyciu również z kodu C, która nie poprawia się po jej przekręceniu. Lepiej to napraw. Użyj MarshalAs.SizeConst, jeśli długość jest przewidywalna. –