Klasy w DLL-kach a inne języki

0

Hey, mam pytanie dot. DLL i ich wykorzystania w innych programach pisanych w innych językach.

Czy jeśli napiszę w C++ DLL-kę z funkcją, która przyjmuje jako argument np. vector<double> to czy jeśli ktoś będzie chciał skorzystać z tej DLL-ki np. pisząc w C# lub Java to czy będzie mógł wywołać tą funkcję? Nie wiem, czy w tych językach jest vector, ale nawet jeśli to pewnie jest troszkę inaczej zdefiniowany...

Drugie pytanie dot. samego wykorzystania klas etc. bo z tego co wiem to każdy język jest podobny ale mimo wszystko trochę się różni między sobą no i zastanawiam się jak taki C#-owiec lub Javo-wiec może wykorzystać moją klasę napisaną w C++? Czy będzie mógł normalnie wywoływać funkcje (metody) i wprowadzać do nich argumenty?

Z góry dziękuję za odpowiedź!

4

To w jaki sposób binarnie wygląda klasa opisuje tzw. ABI danego kompilatora/środowiska. Visual C++ ma swoje, GCC ma swoje i mogą się one różnić pomiędzy konkretnymi wersjami. Nie ma tutaj żadnego standardu, więc raczej nie eksportuje się "gołych" klas (może być to problematyczne nawet w obrębie tego samego środowiska). Powstały natomiast niezależne standardy eksportu i użycia klas, np. bardzo popularny COM. Można w C++ tego typu klasę prosto utworzyć np. za pomocą ATL. Klasy COM można bez problemu używać zarówno w Javie, .NET i innych środowiskach. Jeżeli zależy ci na wieloplatformowym rozwiązaniu to możesz zerknąć np. na XPCOM Mozilli.

2

Czy jeśli napiszę w C++ DLL-kę z funkcją, która przyjmuje jako argument np. vector<double> to czy jeśli ktoś będzie chciał skorzystać z tej DLL-ki np. pisząc w C# lub Java to czy będzie mógł wywołać tą funkcję

Odpowiedź krótka: nie.

Odpowiedź długa: będzie mógł wywołać, ale okaże się to bardzo niepraktyczne, w czym przeszkadzają dwie rzeczy:
· manglowanie nazw, czyli doklejanie przez kompilator znaczków-krzaczków do nazwy funkcji które trzeba „zgadnąć” – a nawet nie mamy gwarancji że schemat pozostaje ten sam w różnych wersjach Visual C++, oraz
· sama implementacja klasy vector i dowolnej innej z STL zmienia się z wersji na wersję, i tutaj wręcz mamy „gwarancję” że vector z Visual C++ 2008 nie jest tym samym vectorem co w 2010, i nie tym samym co w 2012.

Dlatego z DLL eksportuje się funkcje globalne (koniecznie z extern "C") albo klasy COM (co jednak trudno jest zrobić dobrze).

0

Dziękuję za odpowiedzi!
Czyli reasumując DLL raczej nie są przeznaczone dla klas (poza wyjątkami dla bardziej zaawansowanych). Z drugiej strony mogę zrobić wiele funkcji, które będą korzystać z obiektu mojej klasy i wywoływać odpowiednie metody ;).
Mam w takim razie jeszcze pytanie co z wbudowanymi typami np. double, int etc? Czy z nimi również może być problem? Zdaje się, że niektóre zmienne mogą mieć różną ilość bajtów w różnych kompilatorach - np. typ double może mieć 4 lub 8 bajtów. Czy z wbudowanymi zmiennymi również może być problem? I jak przekazywać tablice - czy funkcja, która jako argument ma wskaźnik do tablicy typu double może być wywołana w C# lub Java?
pozdrawiam

1

Wielkość typów wbudowanych jest ustalane na poziomie ABI systemowego i jest raczej spójna między kompilatorami. Jak jest więcej danych do przekazania to z reguły przekazuje się wskaźnik na bufor lub strukturę.

Musisz uważać, aby wszystkie alokacje i dealokacje odbywały się po tej samej stronie - tj. jeśli DLL zaalokowało, to DLL zwalnia; jeśli alokacja była w głównym pliku wykonywalnym, to w DLL tej pamięci nie zwalniasz (chyba ze oba moduły zostały skompilowane tym samym kompilatorem z tymi samymi ustawieniami).

2

Czyli reasumując DLL raczej nie są przeznaczone dla klas (poza wyjątkami dla bardziej zaawansowanych).
Raczej nie. Można eksportować klasę, albo funkcję z klasami w parametrach, ale taka DLL-ka nadaje się wtedy tylko do użytku pod tym samym kompilatorem, w tej samej wersji, co mocno ogranicza jej użycie.

Zobacz jak to robi WinAPI: biblioteki systemowe eksportują funkcje globalne, które operują na różnych HANDLE'ach i podobnych typach danych:

BOOL WINAPI ShowWindow(HWND hWnd, int nCmdShow);

Czym jest to HWND? Dokumentacja mówi tylko a handle to the window, uchwyt na okno. Sam typ HWND jest wskaźnikiem (void*). Na co wskazuje? Tego dokładnie nie wiemy. Na jakąś strukturę, którą Windows zarządza. To po stronie WinAPI odbywa się alokacja tej struktury (w CreateWindow()) i zwolnienie pamięci (w DestroyWindow()). Nie wiemy jakie pola zawiera ta struktura (i może się zmieniać z wersji na wersję Windowsa), a operować na niej możemy tylko poprzez wskaźnik przekazując go do różnych funkcji.

Po stronie Windowsa to może być strukturka typu POD albo wypasiona klasa – ale jedyne co mamy to ten wskaźnik.

0

Czyli jeśli dobrze rozumiem najlepiej jest w DLL-ce utworzyć np. vector obiektów mojej klasy i funkcjami nimi zarządzać tj. np. funkcja, która tworzy nowy obiekt i zwróci jego identyfikator (np. index), funkcja, która wywołuje jakąś metodę na obiekcie, funkcja, która ustawia parametry w obiekcie itd...

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