DLL C++

Jeśli masz coś do powiedzenia w sprawie LabVIEW napisz. Tutaj są tematy, których nie można uściślić do innych działów.
oczekp
Posty: 161
Rejestracja: 22 lis 2009 15:12
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: oczekp »

Dobra to podsumowując, bo się lekko pogubiłem. Sprawa wygląda tak:
1. masz jeden dll, w którym masz różne funkcje.
2. w przypadku wywołania funkcji, w której parametr jest stringiem, czyli w Twoim przypadku jak dll node jest poza strukturą case to jest okej.
3. w przypadku wywołania funkcji, w której parametrem jest tablica, czyli wewnątrz struktury case to wywala błąd:
LabVIEW: An exception occurred within the external code called by a Call Library Function Node. The exception might have corrupted the LabVIEW memory. Save any work to a new location and restart LabVIEW.

Wywołujesz tam jedną i tą samą funkcję dla każdej z tablic? I dla każdej masz błąd? Czy wywołujesz jakieś jeszcze inne i dla nich jest okej?
Z tego błędu co jest zgłaszany to wydaje mi się, że masz coś złego w kodzie c++. Tak jakbyś chciał, albo wpisywał do nieodpowiednich komórek pamięci.

Ciężko mi coś na podstawie kodu powiedzieć, bo musiałbym mieć cały i wiedzieć co chcesz uzyskać itd.
Na pierwszy rzut oka to popatrz sobie na te auto_ptr.
Tak na szybko z wikipedii:
Wzorzec klasy auto_ptr opisuje obiekt przechowujący wskaźnik do zaalokowanego obiektu typu Typ*, dbając o to żeby obiekt na który ten wskaźnik wskazuje został automatycznie zniszczony wraz ze zniszczeniem wskaźnika − czyli zazwyczaj po opuszczeniu zasięgu.
oraz
Klasa auto_ptr ma semantykę ścisłej własności co oznacza że instancja auto_ptr jest jedynym właścicielem obiektu na który ona wskazuje. Przy kopiowaniu auto_ptr, źródłowa instancja ustawia się na wartość null
Może coś kasują jak są wywoływane lokalnie w funkcji i usuwają np dostęp do urządzenia późniejszy w dalszych dll.

Albo np. zamiast tego:

Kod: Zaznacz cały

 case DLL_PROCESS_DETACH:
             {
             delete device1;
           delete device2;
           delete cdev;
           device1 = NULL;
           device2 = NULL;
           cdev = NULL;
             }
                break;
Utwórz sobie jakąś funkcję, która będzie Twoim destruktorem i wtedy sprawdź czy działa.-> To już tak w ramach rozpaczy, co mi przychodzi do głowy:)

Ja zrobiłem sobie podobny kod do Twojego tylko, że na tablicach i zadziałał mi. Z tym, że pamiętaj, że jak na początku tworzysz dynamicznie obiekty to ten dll, w którym to robisz musi się wywołać jako pierwszy. Hierarchie możesz zachować np poprzez łączenie drutem błędu jak w załączniku.

Przydałby się ktoś, co lepiej c++ ogarnia i sprawę dllków:P
Załączniki
snip.png
snip.png (15.9 KiB) Przejrzano 11773 razy
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

DLL C++

Post autor: Dziech »

Dobra to podsumowując, bo się lekko pogubiłem. Sprawa wygląda tak:
1. masz jeden dll, w którym masz różne funkcje.
2. w przypadku wywołania funkcji, w której parametr jest stringiem, czyli w Twoim przypadku jak dll node jest poza strukturą case to jest okej.
3. w przypadku wywołania funkcji, w której parametrem jest tablica, czyli wewnątrz struktury case to wywala błąd:
LabVIEW: An exception occurred within the external code called by a Call Library Function Node. The exception might have corrupted the LabVIEW memory. Save any work to a new location and restart LabVIEW.
Dokładnie
Wywołujesz tam jedną i tą samą funkcję dla każdej z tablic? I dla każdej masz błąd? Czy wywołujesz jakieś jeszcze inne i dla nich jest okej?
Z tego błędu co jest zgłaszany to wydaje mi się, że masz coś złego w kodzie c++. Tak jakbyś chciał, albo wpisywał do nieodpowiednich komórek pamięci.
DLL = 3 funkcje. Pierwsza funkcja to ta z argumentem string poza casem. Druga funkcja z argumentem const double* vlt uruchamia się w dwóch caseach. Trzecia funkcja, ma również argument const double* zer i uruchamia się w jednym z caseów (ostatnim).
Utwórz sobie jakąś funkcję, która będzie Twoim destruktorem i wtedy sprawdź czy działa.-> To już tak w ramach rozpaczy, co mi przychodzi do głowy:)
No próbowałem ; ) Nawet po zakomentowaniu DLLMain ten sam błąd - więc to na pewno nie jest problem.
Ja zrobiłem sobie podobny kod do Twojego tylko, że na tablicach i zadziałał mi. Z tym, że pamiętaj, że jak na początku tworzysz dynamicznie obiekty to ten dll, w którym to robisz musi się wywołać jako pierwszy. Hierarchie możesz zachować np poprzez łączenie drutem błędu jak w załączniku.
Hmm, czy to ma znaczenie ? Tzn. tworzenie obiektów jest w funkcji ze stringiem i faktycznie włożyłem go do sequence1 a potem stworzyłem resztę. Destrukcja powinna być załatwiona przez DLLMain. Inna sprawa - czy po kliknięciu "run" zdarzenia następują w ten sposób : Ładuje DLL - > wykonuję funkcje -> "odładowuję DLL" ?
Ciężko mi coś na podstawie kodu powiedzieć, bo musiałbym mieć cały i wiedzieć co chcesz uzyskać itd.
Na pierwszy rzut oka to popatrz sobie na te auto_ptr.
Kurcze, szczerze mówiąc, nie zauważyłem tego !! : / To może być to. Po prostu nie pracuję ze swoim kodem i są takie wtopy ; ) Dzięki za pomoc, zobaczę co się da zrobić i będę informował : )

D
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: Dziech »

Oddzieliłem funkcję destruction, jak radziłeś i teraz nie wyrzuca błędów : ) Jutro zobaczę czy działa ze sprzętem.

Dzięki za dotychczasową pomoc : )
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

DLL C++

Post autor: Dziech »

Niestety - nic z tego. Działają if'y chyba, więc nie tworzone są obiekty...

A mam pytanie - czy ten łańcuch z pierwszego DLL jest z error out ?
oczekp
Posty: 161
Rejestracja: 22 lis 2009 15:12
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: oczekp »

Ajć szkoda, ale nie poddawaj się:) Coś się wymyśli:]
Nie bardzo rozumiem co masz na myśli pisząc łańcuch z pierwszego DLL jest z error out. Ogólnie w tym co wcześniej wysłałem, opisując ogólnie to jest tak, że wykonywany jest pierwszy Call Library Function Node (dll) i za pomocą drutu przesyłana jest informacja o błędach, które ewentualnie mogły nastąpić. Przekazywane jest to na wejście error in drugiego Call Library Function Node. Sytuacja się to powtarza i analogicznie jak wcześniej po wykonaniu przesyłana jest informacja o błędzie do ostatniego, czyli w tym przypadku destruktora. Po jego wykonaniu jeśli wszystko było po drodze okej, to nic się nie zasygnalizuje i nie wyświetli, natomiast jak wystąpiły błędy to zostaną ukazane.
Tego typu rozwiązanie jest eleganckie jeśli chodzi o obsługę błędów, a dodatkowo wymusza na poszczególnych Call Library Function Node kolejność ich wywołań.
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: Dziech »

Ogólnie w tym co wcześniej wysłałem, opisując ogólnie to jest tak, że wykonywany jest pierwszy Call Library Function Node (dll) i za pomocą drutu przesyłana jest informacja o błędach, które ewentualnie mogły nastąpić.
Pytałem skąd wychodzi drut. Dochodzi do error in, a wychodzi z error out tak ? Po prostu trochę się na Twoim diagramie przesunęło i wyglądało jakby drut nie wychodził z error out, tylko z funkcji void. Ale domyślam się, że ma wychodzić z error out. Nieważne ; )

Generalnie udało mi się zdebuggować działanie VI za pomocą VS i miałeś rację - najprawdopodobniej coś z inicjalizacją obiektów. Także teraz czekam na poprawiony kod i zobaczymy czy się uda : )
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

DLL C++

Post autor: Dziech »

Hm, działa jeden case : ) Co jest pozytywne. Problemem było coś w kodzie "wyżej".

Teraz mam dostęp do funkcji, które zwracają liczbę elementów w arrayach w moich caseach. Zaczynam wyszukiwanie informacji jak zinicjalizować array (to akurat wiem), żeby dostępnych było tyle indeksów co liczba elementów. Niestety problem w tym, że zamiast indeksów mam napisy : ) Ale będę próbował :)
oczekp
Posty: 161
Rejestracja: 22 lis 2009 15:12
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: oczekp »

Coś się chociaż ruszyło:)
Zaczynam wyszukiwanie informacji jak zinicjalizować array (to akurat wiem), żeby dostępnych było tyle indeksów co liczba elementów.
A to w Labview czy w C++ potrzebujesz?
Jak w c++ to dajesz:

Kod: Zaznacz cały

int tab[] = new int[rozmiar]; //utworzenie, gdzie rozmiar możesz sobie przesłać jako argument
delete[] tab; //usunięcie, zwolnienie pamięci po wykorzystaniu
Jeżeli np. potrzebujesz w dll wykonać jakieś operacje na tablicy, a później zwrócić ją z powrotem do labview to utwórz taką tablicę w labview, prześlij do dll jej referencję (wskaźnik), a następnie wykonaj co masz i odbierz wynik w LV. [załącznik]

Nie bardzo rozumiem o co chodzi z tymi napisami:)
Załączniki
do_kwad.zip
(11.94 KiB) Pobrany 285 razy
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: Dziech »

Nie nie ; ) Takie podstawy cpp to znam ; P Ale dziękuję : )

Chodzi o LabVIEW. Aktualnie mój problem polega na tym, że mam listę, może być enum, albo text ring. Generalnie strings i chcę wyciągnąć z tej listy tylko tyle ile mi potrzeba po podaniu int'a. Zaraz na to wpadnę... : D

Na pierwszej stronie przeczytasz co konkretnie mam http://labview.pl/viewtopic.php?f=3&t=3656
Ostatnio zmieniony 23 sie 2011 15:37 przez Dziech, łącznie zmieniany 2 razy.
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: Dziech »

Zrobiłem to w ten sposób. Ale coś chyba nie działa. Eniłej - całość niby działa, ale raczej wysyła do urządzenia jakieś randomowe wartości... Damnn


W załączniku Drugi inicjalizuję tablicę, ale stało się coś dziwnego i nie wczytuje liczby zwracanej przez DLL node'a. Typ to tak naprawdę size_t. W Labview używam unsigned... no cóż, próbowałem chyba wszystkich...
Załączniki
Drugi
Drugi
Bez tytułu.png (8.91 KiB) Przejrzano 11739 razy
Pierwszy
Pierwszy
Bez tytułu.png (5.31 KiB) Przejrzano 11742 razy
oczekp
Posty: 161
Rejestracja: 22 lis 2009 15:12
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: oczekp »

Co do pierwszego wygląda okej, ale:
z pierwszego dlla coś zwracasz, domyślam się, że to ilość liczb, które masz wybrać z tabeli Zernike (ten rozmiar to jest jakaś zmienna globalna?). Jeżeli tak to po pierwsze zabezpiecz się na wypadek, jakby długość, którą podajesz w Array Subset była większa niż rozmiar tablicy Zernike, bo jak w tym drugim dll kręcisz np. fora po wielkości tej zmiennej globalnej to Ci za zakres wyjedzie i głupoty wyjdą.
A reszta wygląda sensownie.
W załączniku Drugi inicjalizuję tablicę, ale stało się coś dziwnego i nie wczytuje liczby zwracanej przez DLL node'a. Typ to tak naprawdę size_t. W Labview używam unsigned... no cóż, próbowałem chyba wszystkich...
Trochę za chaotycznie piszesz albo ja nie rozumiem:P Co, gdzie, jak:)
Gdzie inicjalizujesz tablice?:)
Jaki typ to size_t?
Ja widzę to tak, że w pierwszym dll masz funkcję, która wygląda siakoś tak:
uint8 fun1(); zwraca typ U8;
Druga to za pewne jakaś funkcja
void fun2(double *tab);
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: Dziech »

oczekp pisze:Co do pierwszego wygląda okej, ale:
z pierwszego dlla coś zwracasz, domyślam się, że to ilość liczb, które masz wybrać z tabeli Zernike (ten rozmiar to jest jakaś zmienna globalna?). Jeżeli tak to po pierwsze zabezpiecz się na wypadek, jakby długość, którą podajesz w Array Subset była większa niż rozmiar tablicy Zernike, bo jak w tym drugim dll kręcisz np. fora po wielkości tej zmiennej globalnej to Ci za zakres wyjedzie i głupoty wyjdą.
A reszta wygląda sensownie.
Takiej sytuacji nie będzie, ale popracuję nad tym potem : ) Masz rację.
oczekp pisze:
W załączniku Drugi inicjalizuję tablicę, ale stało się coś dziwnego i nie wczytuje liczby zwracanej przez DLL node'a. Typ to tak naprawdę size_t. W Labview używam unsigned... no cóż, próbowałem chyba wszystkich...
Trochę za chaotycznie piszesz albo ja nie rozumiem:P Co, gdzie, jak:)
Gdzie inicjalizujesz tablice?:)
Jaki typ to size_t?
Ja widzę to tak, że w pierwszym dll masz funkcję, która wygląda siakoś tak:
uint8 fun1(); zwraca typ U8;
Druga to za pewne jakaś funkcja
void fun2(double *tab);

jest tak : funkcja w DLL jest : size_t nChannels(void) { return size_t Channels; }

Pewnie coś tam się dzieje w niej jeszcze, ale to nie istotne. W Labview nie da się wybrać typu zwracanego size_t. No, ale przed minutą to przestał być problem, bo kolega zmienił size_t na int : ) No i teraz : wsadzam indicator za tym co zwraca funkcja i jest okrąglutkie 0 : / A działało ! Wcześniej po run array na front panelu się rozwijał do tych nChannel kolumn ( w moim wypadku teraz 18). A teraz jest 1 a size z Channel Control zwraca 0 : /


P.S Dodam, że nChannels zwraca wartość zawartą w pliku, który czytam wcześniej .dmc
Załączniki
Czytanie Pliku
Czytanie Pliku
Ostatnio zmieniony 23 sie 2011 17:40 przez Dziech, łącznie zmieniany 1 raz.
oczekp
Posty: 161
Rejestracja: 22 lis 2009 15:12
Wersja środowiska: LabVIEW 2010

DLL C++

Post autor: oczekp »

a nie możesz po prostu zamienić tego size_t w kodzie na np. unsigned int i wtedy będziesz miał pewność o jaki typ chodzi:P
Albo w labview w dll ustaw unsigned int i zobaczy czy sobie poradzi.
Zazwyczaj, aczkolwiek nie zawsze size_t to :

Kod: Zaznacz cały

typedef usigned int size_t;
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

Re: DLL C++

Post autor: Dziech »

Tak, czytałem, ale to nie ma znaczenia - typ został zmieniony w źródle. To nie ważne. Teraz tylko problem, bo LV nie chce czytać mi tego pliku w ogóle : / Bo skoro widzi pod zmienną channels 0 to znaczy, że nie czyta poprawnie pliku.
Dziech
Posty: 34
Rejestracja: 11 sie 2011 12:19
Wersja środowiska: LabVIEW 2010

DLL C++

Post autor: Dziech »

A słuchajcie, mam takie pytanie - jak LabVIEW otwiera DLL ? Przypuśćmy, że mam dwa node'y DLL, połączone łańcuchem.

Czy jest tak :

LV otwiera DLL -> ładuje argumenty do funkcji -> wykonuje funkcje -> return(); -> zamyka DLL -> Otwiera DLL w nowym nodzie -> ładuje argumenty do funkcji -> wykonuje funkcje -> return();

Czy :

LV otwiera DLL -> ładuje argumenty do funkcji -> wykonuje funkcje -> return(); -> ładuje argumenty do funkcji w drugim nodzie -> wykonuje funkcje -> return();


Jeśli to pierwsze - jak zachować obiekty utworzone przez LV w pamięci ?
Ostatnio zmieniony 25 sie 2011 11:32 przez Dziech, łącznie zmieniany 1 raz.
ODPOWIEDZ