Mam projekt C#, chciałbym wykorzystać pewne funkcje / pliki napisane w C++ (jest pewien open source z funkcjami realizującymi pewne interesujące mnie zadania - ale napisane pliki są w C++). Jak najlepiej do tego podejść ? (być może to proste ale zawsze lepiej zapytać ) :)
Dokładnie rzecz biorąc jest tam funkcja int funkcja(int zm1, int *zm2, int *zm3); <- jak skorzystać z takiej funkcji z poziomu C#, jak podczepić pliki itd - proszę o pomoc ! :)
popcio36 napisał(a)
Mam projekt C#, chciałbym wykorzystać pewne funkcje / pliki napisane w C++ (jest pewien open source z funkcjami realizującymi pewne interesujące mnie zadania - ale napisane pliki są w C++). Jak najlepiej do tego podejść ? (być może to proste ale zawsze lepiej zapytać ) :)
Dokładnie rzecz biorąc jest tam funkcja int funkcja(int zm1, int *zm2, int *zm3); <- jak skorzystać z takiej funkcji z poziomu C#, jak podczepić pliki itd - proszę o pomoc ! :)
Nie mozesz tego przeportowac na C#? JEsli chodzi o wskazniki to mozesz to upchac do UNSAFE
przeportować ? Co masz na myśli ? A co z np fragmentami #include, które nie występuje w C# ? (To nie jeden plik tylko sporo plików .cpp oraz .h korzystających z siebie wzajemnie, których efektem jest funkcja znajdująca się w jednym z nich właśnie taka jak pokazałem powyżej)
taki_tam_pomysl napisał(a)
Nie mozesz tego przeportowac na C#? JEsli chodzi o wskazniki to mozesz to upchac do UNSAFE
Świetny pomysł. Spróbuj w ten sposób "przeportować" cokolwiek.
A problem nazywa się po angielsku managed/unmanaged code interoperability. Google zna bardzo wiele tutoriali na ten temat.
Przeczytałem klika artykułów i wyglada to dość ciężko. Ma ktoś większe doświadczenia z tym zeby mi pomóc ? Powtórzę, że mam szereg plików cpp oraz h. Interesuje mnie funkcja w jednym z nich (funkcja nadrzędna korzysta ona z funkcji w innych plikach). Co musze zrobić po kolei ?
Skompiluj to jakimś kompilatorem c++ do biblioteki dll. Resztę pokrywają artykuły w/w.
napotkałem na następujący problem - pliki były pisane pod Linuks i używa tam #include m<mem.h> oraz funkcji memmove. Zmieniłem mem.h na memory.h (tak gdzieś przeczytałem) ale nie widzi memmove. Jak sobie z tym poradzić ?
string.h zaincluduj.
Tak jak pisali przedmówcy - skompiluj to do dll - tylko pamiętaj żeby nie eksportować klas (tylko funkcje) i bez kluczowania nazw (extern "C"). Jak importowac natywne dll-ki - znajdzesz wszedzie przykłady albo obejrzyj sobie jak .net inportuje dll-ki natywne z windows.
Unsafe i wskazniki sobie daruj, uzywaj tylko w ostatecznosci
Ok więc postęp jest taki:
W dll-ce mam moją funkcję zrobioną tak:
extern "C" __declspec(dllexport) int __stdcall BeatDetectAndClassify(int ecgSample, int *beatType, int *beatMatch)
następnie w aplikacji C# mam
[DllImport("AnalizaDLL.dll")]
public static extern int BeatDetectAndClassify(int ecgSample, ref int beatType, ref int beatMatch);
i za chiny nie potrafię zrobić żeby funkcja z dll-ki zmieniała mi te "beatType" i "beatMatch". Próbowałem kilku sposbów - nadaremnie. Funkcja zwraca dobrą wartość ale nie potrafi zaingerować w przekazywaną zmienną. Jak rozwiązać ten problem żeby beatType i beatMatch były do zmienienia przez ten kod niezarządzany w dll-ce.
dziwne. powinno dzialac, oznaczyles prawidlowo ref.. jezeli CLR nie rzuca wyjatkiem ze funkcji nieodnaleziono, to znaczy ze sygnatury dopasowal i powinien sobie poradzic z ref int <-> int* i powinno to byc domyslnie dwukierunkowe..
opcja 1wsza - CLR z jakiegos powodu nie uznal tych parametrow za dwukierunkowe, trzeba mu podpowiedziec.
sprobuj wiec tak dla 100% pewnosci podac explicite kierunek marshallingu.. moze pomoze, ale IMHO to juz zbytni verbose:
[DllImport("AnalizaDLL.dll")]
public static extern int BeatDetectAndClassify(int ecgSample, [IN][OUT] ref int beatType, [IN][OUT] ref int beatMatch);
czy te dwa int to sa tylko dodatkowe wartosci zwracane, czy tez faktyczne referencje? zasady oznaczania parametrow w skrocie:
- int* - jak tylko wyjscia, to wystarczy [OUT] out int
- int*, int& - jak funkcja oglada wartosci zawarte tych zmiennych i potem je 'poprawia', to musi byc [IN,OUT] ref int
- int - jak by z kolei to byl zwykly parametr - [IN] int
opcja 2ga, bardziej mi prawdopodobna -- wszystko dziala, to po prostu ta funkcja NIE przypisala z jakiegos powodu tych wartosci.. sprawdz wartosci innych parametrow, upewnij sie ze sa prawidlowe.