Poprawne importowanie funkcji z C/C++ do C# - jak poradzić sobie z "unsigned char"?

0

Dzień dobry.

Mam funkcję którą importuję z pliku dll napisanego w c/c++, piszę program w c#. Wszystkie importowane funkcje działają prawidłowo. Nie potrafię jednak importować poprawnie tej funkcji:

void ReceiveFrame( unsigned char *TargetAddress, unsigned char *DataLength, unsigned char *ModuleAddress )

Działanie:
Funkcja kopiuje do bufora docelowego odebraną ramkę, a także przekazuje informacje o jej długości oraz adresie modułu, od którego pochodzi.

Parametry przyjmowane:

  • unsigned char *TargetAddressadres bufora docelowego
  • unsigned char *DataLengthadres zmiennej, do której ma być przekazana informacja o długości ramki, w skład której wchodzą: rozkaz, parametry operacji oraz w przypadku ramki odpowiedzi kod operacji
  • unsigned char *ModuleAddressadres zmiennej, do której ma być przekazana informacja o adresie modułu nadawczego

Wartość zwracana:

Brak.

Próbowałem w ten sposób:

import

[DllImport("NetrRs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void _ReceiveFrame(byte[] TargetAddress, IntPtr DataLength, IntPtr ModuleAddress);

wykonanie

byte[] ramka_odpowiedzi = new byte[2];
IntPtr dlugosc_ramki = Marshal.AllocHGlobal(1);
IntPtr adres_modulu = Marshal.AllocHGlobal(1);
NetrRs._ReceiveFrame(ramka_odpowiedzi, dlugosc_ramki, adres_modulu);

Ramka_odpowiedzi zapisywana jest poprawnie, jednak długosc_ramki i adres_modulu zamiast wartości 1 i 6 przyjmuje wielocyfrowe wartości.

Kiedy zamiast IntPtr korzystałem z byte - wyrzucało taki błąd:

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

Jak poradzić sobie z unsigned char* w c# w tym wypadku? Bardzo proszę o pomoc :)

poprawienie tematu wątku, dodanie znaczników <code class="csharp"> i <quote> dla treści błędu oraz dodanie wypunktowania - fp

2
  1. Napisałem bzdurną DLL-kę do testów:
void ReceiveFrame( unsigned char *TargetAddress, unsigned char *DataLength, unsigned char *ModuleAddress )
{
	for (int i=0; i<10; i++)
		TargetAddress[i] = i;

	*DataLength = 10;
	*ModuleAddress = 42;
}
  1. Przykład użycia:
[DllImport(@"test.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void ReceiveFrame([Out] byte[] TargetAddress, out byte DataLength, out byte ModuleAddress);

static void Main(string[] args)
{
	byte[] bufor;
	byte len, adr;

	// alokujemy miejsce na bufor, 255 wystarczy, skoro zakładamy jeden bajt rozmiaru
	bufor = new byte[255];

	ReceiveFrame(bufor, out len, out adr);
            
	// nasza tablica nadal ma rozmiar 255, ale wypełnionych jest tylko `len` pierwszych elementów

	Console.WriteLine("DataLength = {0}", len);
	Console.WriteLine("ModuleAddress = {0}", adr);
	for (int i=0; i<len; i++)
		Console.Write("{0} ", bufor[i]);
}
  1. Wynik:
DataLength = 10
ModuleAddress = 42
0 1 2 3 4 5 6 7 8 9
0

Dziękuję za pomoc, działa. Pozdrawiam:)

1 użytkowników online, w tym zalogowanych: 0, gości: 1