Przekazywanie tablicy dwuwymiarowej do biblioteki w C++

0

Witam Wszystkich.
Na początku chciałbym zaznaczyć, że przeszukałem już chyba wszystkie możliwe wyniki z googla w poszukiwaniu odpowiedzi. Zarówno po polsku jak i po angielsku.

Mój problem polega na przekazaniu dynamicznie stworzonej tablicy do biblioteki w C++ (a także do Asemblera, bo taki dostałem projekt).

Tablica w C# jest zdefiniowana następująco:

 double[,] MacierzA = new double[rozmiar, rozmiar]; //deklaracja macierzy A 

Po dynamicznym załadowaniu wszystkich bibliotek
deklaruję delegacje

licz Licz = (licz)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(licz)); 

Oraz wywołuję funkcję z parametrem rozmiar (na razie zakładam stały rozmiar, ale ma być docelowo wczytany z pliku bądź wpisany)

 MessageBox.Show(Licz(rozmiar, MacierzA).ToString(), "Wynik", MessageBoxButtons.OK);

Wyświetlam wynik w messagebox, ale to na razie nie ma mniejszego znaczenia.
Chodzi o sam fakt, jak wywołać tę funkcję, gdyż za każdym razem coś się nie zgadza podczas kompilacji, a jesli już jest OK, to w bibliotece mam problem z zarządzaniem tą tablicą.
Najlepiej by było, gdybym przekazywał wskaźnik do tej tablicy dwuwymiarowej, no ale nie mam pojęcia jak i tutaj proszę o pomoc.

Jako gratis dodaję jeszcze fragment biblioteki w C++:

 extern "C" BIBLIOTEKAC_API double** licz(int rozmiar, double** MacierzA)
{
double **Macierz1 = new double * [rozmiar]; //deklaracja tablicy dynamicznej dwuwymiarowej o wymiarze ROZMIAR
   for (int j=0; j<rozmiar; j++){
     Macierz1[j] = new double[rozmiar];
   }
double **MacierzA1 = new double * [rozmiar];
	for (int j=0; j<rozmiar; j++){
		MacierzA1[j] = new double[rozmiar];
	}
	MacierzA1[0][0] = MacierzA[0][0];
//// Wypełnianie macierzy uprzednio zadeklarowanej jedynkami
	for (int i = 0; i < rozmiar; i++) // tworzenie macierzy jedynkowej
		for (int j = 0; j < rozmiar; j++)
			{
				if (i == j)
				Macierz1[i][j] = 1;
			}

// Liczenie macierzy odwrotnej metodą Gaussa-Jordana
for(int q=0;q<rozmiar;q++)									
	{														
		double temp=MacierzA[q][q];							
		for(int j=0;j<rozmiar;j++)							
		{
			MacierzA[q][j]/=temp;									
			Macierz1[q][j]/=temp;								
		}											
		for(int i=0;i<rozmiar;i++)					
		{
			temp=MacierzA[i][q];					
			for(int j=0;j<rozmiar;j++)		
			{								
                if (i != q)
                {                        							
                    MacierzA[i][j] -= MacierzA[q][j] * temp;			
                    Macierz1[i][j] -= Macierz1[q][j] * temp;
                }                                    
			}
		}
	}
	
	return Macierz1;
}
1

Na razie pomijając kwestię marshallingu (dlaczego jakieś GetDelegateForFunctionPointer a nie po prostu DllImport?), to zwracanie nowo przydzielonej pamięci po stronie C++ jako wyniku funkcji nie jest zbyt dobrym pomysłem. Jak potem tę macierz chcesz zwolnić z C#? Nie da się, więc trzeba pamiętać o wywołaniu drugiej funkcji w C++, która będzie tylko zwalniać pamięć.

Rozumiem że takie są wymogi zadania. Jest ono do kitu, bo do tego się używa C++/CLI ;-)

Ale wracając...

w C# definiujesz tablicę dwuwymiarową, double[,]. w C++ zaś jako tablicę tablic, czyli double[][]. hmm, nie jestem pewiem, czy zdajesz zobie sprawę z różnicy. Te dwa typy mają zupełnie inaczej rozłożone dane, więc „przekazanie wskaźnika” nie wchodzi w grę.

Być może da się uzyskać marshalling takiej tablicy jakąś kombinacją alpejską w standardowy sposób, ale ja bym polecił custom marshalling, czyli [MarshalAs(UnmanagedType.CustomMarshaler)].
Poszukaj przykładów, ale nie jest to wdzięczny temat.

bo taki dostałem projekt
Najlepiej podaj treść, co to ma dokładnie być, i co ma robić.

0

Dzięki Azarien ! Dałem sobie już z tym radę. No mamy mieć GUI i dwie dll'ki jedną w języku wysokiego poziomu C/C++ oraz w ASM. Ja dostałem obracanie macierzy.

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