Goto page Previous 1, 2, 3 ... 22, 23, 24
heby
Guest
Mon Jul 25, 2022 2:31 pm
On 25/07/2022 15:33, Piotr Gałka wrote:
Quote:
Ale moim celem było, aby tego GUID wpisać tylko i wyłącznie jako
parametr wywołania funkcji - pominąć potrzebę robienia przeze mnie
zmiennej tego typu.
Twój przykład nawet stosując referencje nie realizuje tego co ja wtedy
chciałem osiągnąć.
W tym Twoim przykładzie?:
---------------
static GUI konkretnyGUID = { };
class KlasaKonkretna : public KlasaBazowa {
public:
KlasaKonkretna() : KlasaBazowa( konkretnyGUID ) { [...] };
[...]
};
---------------
Mi chodziło o to aby: nie tworzyć statycznej zmiennej konkretnyGUID
tylko zapis jego wartości ująć jakoś od razu w miejscu gdzie go
wstawiłeś jako parametr konstruktora KlasyBazowej w konstruktorze Klasy
konkretnej.
Nie rozumiem jaki by to miało mieć zysk.
Gdzieś to musisz trzymać.
Możesz zrobić tak:
class KlasaBasowa {
[...]
virtual GUI& getGUID() = 0;
};
class KlasaKonkretna : public KasaBazowa {
[...]
GUID& getGUID() override {
static GUID guid = { };
return guid;
}
}
Ale zysk taki, że masz metodę wirtualną ale nie masz pola w klasie bazowej.
Quote:
Konstruktor KlasyKonkretnej najchętniej zostawiłbym w pliku h, a takie
static konkretny GUID to dla mnie musi być w pliku cpp więc i
konstruktor trzeba tam przenieść.
Dlaczeo konstruktor chcesz mieć w h? Zwyczajowo nie ma powodów tego.
Quote:
Ja chciałem zrobić coś podobnego jak mam definiowane mikrokontrolery.
Mam:
class ATProg : public ATProc
{
....
public:
ATProg(dword fs,dword fp,dword es,dword ep,qeord fm,dword
sg):ATProc(...){}
};
I potem już konkretne są definiowane tak:
class ATmega162Prog : public ATProg
{
public:
ATmega162Prog():ATProg(0x4000,128,512,1,0x1EFFFF,0x1E9404){}
};
No wiec w czym problem?
class KlasaBazowa {
public:
KlasaBasowa( int a1, int a2, int a3m int a4 );
[...]
};
class KlasaKonkretna : publci KlasaBazowa {
public:
KlasaKonkretna() : KlasaBazowa( 1,2,3,4 ) { };
};
Quote:
Czyli konstruktor klasy bazowej miał mieć jeden parametr typu GUID a
konstruktory kolejnych klas miały go wołać wpisując tam wartość tego GUIDa.
No to dokładnie tak to opisałem.
Być może widzisz to jako problem, że ten GUID jest widoczny przez cały
czas trwania programu w zmiennej globanej, do której przekazujesz
referencje. To jest szybkie - nie trzeba go w miejscu inicjować za
każdym razem.
Quote:
Wiem, że mi się to nie udało. Ogólnie wiem, że nie udawało mi się wpisać
GUIDA jako parametru wywołania konstruktora (bezpośrednio w wywołaniu).
Jesli mówisz o inicjacji w miejscu, to powinno dać radę tak:
struct GUID {
int a1;
int a2;
};
class KlasaBazowa {
public:
KlasaBazowa( GUID const& _gui ) { /*tu mam GUID*/ };
};
class KlasaKonkretna : public KlasaBazowa {
public:
KlasaKonkretna() : KlasaBazowa( {1,2} ) { }
};
Zmienna istnieje tylko na czas wołania konstruktora KlasaBazowa. Musi
być wykorzystana w nim i nie wolno przetrzymać referencji na dłużej
(choć można zrobić kopię). Zapis {1,2} inicjuje GUIDa w miejscu i jest z
nowego C++, w starym to pewnie będzie "GUID(1,2)", zalezy jaki konstruktor.
Piotr GaĹka
Guest
Mon Jul 25, 2022 4:00 pm
W dniu 2022-07-25 o 16:31, heby pisze:
Quote:
Mi chodziło o to aby: nie tworzyć statycznej zmiennej konkretnyGUID
tylko zapis jego wartości ująć jakoś od razu w miejscu gdzie go
wstawiłeś jako parametr konstruktora KlasyBazowej w konstruktorze
Klasy konkretnej.
Nie rozumiem jaki by to miało mieć zysk.
Bo to być może nie da się zrozumieć - jakieś chore moje koncepcje :)
Dla Ciebie 'zysk' to jakieś oszczędności pamięci lub czasu realizacji.
A dla mnie zysk z takiego podejścia polega na tym, że dopisanie kolejnej
klasy to byłoby kilka linijek w jednym pliku, a nie po kilka w dwu plikach.
Jak nowa klasa nie wymaga nic w pliku cpp to dopisuję ją tylko do
jednego wspólnego dla wszystkich tych klas pliku h.
Jak wymaga też czegoś w pliku cpp to w moim pojęciu wypada już całą ją
przenieść do plików h i cpp opisujących urządzenie (inna klasa) które
korzysta z tej bazowej tabelki w której to jest mi potrzebny GUID.
Ale nie jestem do tego aż tak przywiązany.
Quote:
Możesz zrobić tak:
class KlasaBasowa {
[...]
virtual GUI& getGUID() = 0;
};
class KlasaKonkretna : public KasaBazowa {
[...]
GUID& getGUID() override {
static GUID guid = { };
return guid;
}
}
Jak mi się nie udało to zrobiłem podobnie jak napisałeś w powyższym
przykładzie tylko nie w tej klasie a w klasie wołającej jej funkcję
wyszukania wszystkich urządzeń - tam robię lokalnego GUID i go używam.
Quote:
Ale zysk taki, że masz metodę wirtualną ale nie masz pola w klasie bazowej.
Patrzysz cały czas na kod wynikowy, a mi chodziło o krótkość zapisu.
Wszystkie używane guidy mam zebrane razem w jednym miejscu - to jest dla
mnie zaleta.
Quote:
Dlaczeo konstruktor chcesz mieć w h? Zwyczajowo nie ma powodów tego.
Jak konstruktor tylko woła kontruktor klasy bazowej wstawiając tam
konkretne liczby to jak go napiszę w h to chyba on nawet zrobi się sam
inline.
Quote:
Ja chciałem zrobić coś podobnego jak mam definiowane mikrokontrolery.
Mam:
class ATProg : public ATProc
{
....
public:
ATProg(dword fs,dword fp,dword es,dword ep,qeord fm,dword
sg):ATProc(...){}
};
I potem już konkretne są definiowane tak:
class ATmega162Prog : public ATProg
{
public:
ATmega162Prog():ATProg(0x4000,128,512,1,0x1EFFFF,0x1E9404){}
};
No wiec w czym problem?
Problem, że jak chciałem tak zrobić to mi nie wyszło. Nie potrafiłem
wpisać wartości konkretnego guid jako parametr w wywołaniu konstruktora
klasy bazowej. O tym, że nie potrafiłem go wpisać w miejsce parametru
już chyba trzeci raz piszę.
Quote:
class KlasaBazowa {
public:
KlasaBasowa( int a1, int a2, int a3m int a4 );
[...]
};
class KlasaKonkretna : publci KlasaBazowa {
public:
KlasaKonkretna() : KlasaBazowa( 1,2,3,4 ) { };
};
Czyli konstruktor klasy bazowej miał mieć jeden parametr typu GUID a
konstruktory kolejnych klas miały go wołać wpisując tam wartość tego
GUIDa.
No to dokładnie tak to opisałem.
Tak, ale z liczbami int.
Wiem tyle, że jak chciałem tak zrobić z guid to mi nie wyszło.
Quote:
Być może widzisz to jako problem, że ten GUID jest widoczny przez cały
czas trwania programu w zmiennej globanej, do której przekazujesz
referencje. To jest szybkie - nie trzeba go w miejscu inicjować za
każdym razem.
Wiem, że mi się to nie udało. Ogólnie wiem, że nie udawało mi się
wpisać GUIDA jako parametru wywołania konstruktora (bezpośrednio w
wywołaniu).
Jesli mówisz o inicjacji w miejscu, to powinno dać radę tak:
struct GUID {
int a1;
int a2;
};
class KlasaBazowa {
public:
KlasaBazowa( GUID const& _gui ) { /*tu mam GUID*/ };
};
class KlasaKonkretna : public KlasaBazowa {
public:
KlasaKonkretna() : KlasaBazowa( {1,2} ) { }
};
Zmienna istnieje tylko na czas wołania konstruktora KlasaBazowa. Musi
być wykorzystana w nim i nie wolno przetrzymać referencji na dłużej
(choć można zrobić kopię). Zapis {1,2} inicjuje GUIDa w miejscu i jest z
nowego C++, w starym to pewnie będzie "GUID(1,2)", zalezy jaki konstruktor.
Zaczyna to być jakby w tym kierunku co ja kombinuję.
Tylko wiem, że nie udało mi się wtedy tego zapisać tak, aby kompilator
przyjął. Nie udało mi się też konwertować bufora bajtów w guid, czy
jakiegoś innego zapisu np kilku wordów w guid.
Ale to było ileś lat temu. Teraz powinienem ponownie popróbować, aby
wskazać co konkretnie mi nie wychodzi, ale mam zero czasu.
Poprzedni post przerwałem bo coś miałem zrobić. Jak tylko to skończyłem
to piszę ten, a w międzyczasie ustaliliśmy tu, że muszę się pilnie czymś
kolejnym zająć (potrzebne na środę) no i znów nie dojdę do powtarzania
eksperymentów.
Po prostu okazja, aby o tym pogadać trafiła się gdy inne zadania
zabierają totalnie czas. Niektóre plany i tak już nieco zawaliłem.
P.G.
heby
Guest
Mon Jul 25, 2022 4:12 pm
On 25/07/2022 18:00, Piotr Gałka wrote:
Quote:
Dla Ciebie 'zysk' to jakieś oszczędności pamięci lub czasu realizacji.
Tak, to w końcu embedded, każdy bajt sie liczy.
Quote:
A dla mnie zysk z takiego podejścia polega na tym, że dopisanie kolejnej
klasy to byłoby kilka linijek w jednym pliku, a nie po kilka w dwu plikach.
To troche stoi w poprzek koncepcji hermetyzacji. Skogo GUID jest
specyficzny dla konkretnej implemetacji klasy, składanie ich w jednym
plików jest nierozsądne, nie powinny wiedzieć o swoim istnieniu.
W ogóle twój przykład wygląda jak próba emualacji Fabryki/Buildera na
konstruktorach. W większych kawałkach kodu było by to zapewne wytknięte
na review ;)
Quote:
Dlaczeo konstruktor chcesz mieć w h? Zwyczajowo nie ma powodów tego.
Jak konstruktor tylko woła kontruktor klasy bazowej wstawiając tam
konkretne liczby to jak go napiszę w h to chyba on nawet zrobi się sam
inline.
inline może zrobić się również, kiedy jesteś w pliku cpp. Zainteresu się
"lto" - w embedded to może być krytycznie ważny bajer, a mało kto
piszący kod na uC wie że w ogóle istnieje.
Quote:
Zaczyna to być jakby w tym kierunku co ja kombinuję.
Tylko wiem, że nie udało mi się wtedy tego zapisać tak, aby kompilator
przyjął. Nie udało mi się też konwertować bufora bajtów w guid, czy
jakiegoś innego zapisu np kilku wordów w guid.
Nowe C++ mają interesujace metody inicjacji struktur, może warto
zainteresować się własnie dlatego standardami C++xx. Jedna już Ci
pokazałem: { 10, 20 } konstruje strukturę z dwoma intami, jesli
występuje w kontekscie, gdzie takie coś jest sensowne.
Piotr GaĹka
Guest
Mon Jul 25, 2022 6:40 pm
W dniu 2022-07-25 o 18:12, heby pisze:
Quote:
On 25/07/2022 18:00, Piotr Gałka wrote:
Dla Ciebie 'zysk' to jakieś oszczędności pamięci lub czasu realizacji.
Tak, to w końcu embedded, każdy bajt sie liczy.
Już co najmniej kilka razy przewinęła się informacja, że ja pod
Builderem, a nie embedded.
Piszę sobie programiki które się komunikują z embedded, ale same nie są
embedded i kilka bajtów w tę czy tamtą mnie nie rusza.
Quote:
To troche stoi w poprzek koncepcji hermetyzacji. Skogo GUID jest
specyficzny dla konkretnej implemetacji klasy, składanie ich w jednym
plików jest nierozsądne, nie powinny wiedzieć o swoim istnieniu.
Od strony embedded - oczywiście masz rację. To są osobne urządzenia i
nic jednemu do drugiego.
Ale ja piszę o moim programie komunikującym się z nimi.
Potrzebuję zdefiniować N pochodnych klasy Tabelka z których każda z nich
robi dokładnie to samo ale posługuje się innym GUID.
Jak definicje klas pochodnych byłyby kilkulinijkowe w pliku h to jak dla
mnie bardzo rozsądne jest mieć je wszystkie razem. Jak piszę program,
który komunikuje się z jakimś z naszych urządzeń to wkładam ten plik i
mogę działać.
Mój program często komunikuje się z wieloma z tych urządzeń.
Na przykład program produkcyjny.
Najpierw wrzuca do mikrokontrolera urządzenia program testowy.
W tym celu używa naszego programatora PDI (GUID nr 1).
Następnie przeprowadza test urządzenia.
W tym celu używa testera (GUID nr 2). W czasie testu z urządzeniem łączy
się przez jego normalne kanały komunikacyjne. Jeśli jest to urządzenie
USB to jego program testowy to GUID nr 3.
Jak wszystko dobrze to pobiera odpowiedni HEX, wkłada do niego numer
urządzenia i zestaw kluczy dla niego.
Klucze pobiera z kolejnego urządzenia - GUID nr 4.
Programuje urządzenie. Po zaprogramowaniu jeszcze ostatnia kontrola -,
czy urządzenie prawidłowo się odzywa. Jeśli jest to urządzenie USB to
będzie to GUID nr 5.
To w przypadku produkcji jednego urządzenia.
Ale ten program, służy do produkcji wszystkich naszych produktów. Dla
drugiego urządzenia USB dojdą kolejne dwa GUIDy bo program testowy dla
innego hardware'u będzie miał swój GUID i docelowy program znów swój.
Mi pasuje jak tabelki umiące wyszukiwać urządzenia o poszczególnych
GUIDach są zdefiniowane w jednym pliku.
Być może template miałoby tu faktycznie sens żeby do programu weszły
tylko te wersje faktycznie użyte, ale jak poszczególne klasy to tylko
inny konstruktor i być może (zapisany w h) robiony z automatu jako inline.
Quote:
inline może zrobić się również, kiedy jesteś w pliku cpp. Zainteresu się
"lto" - w embedded to może być krytycznie ważny bajer, a mało kto
piszący kod na uC wie że w ogóle istnieje.
Ja też nie wiem. Nie piszę embedded.
O ile pamiętam w pliku cpp też mogę użyć słowa inline (nigdy nie
użyłem), które dla kompilatora jest jedynie wskazówką.
Zamiast tego wolę to co chciałbym inline zapisać w h.
Zazwyczaj funkcje w klasie, które korzystają z innej funkcji jedynie
wstawiając jakiś parametr zapisuję od razu w h.
Na przykład typową moją funkcją w klasie jest:
void RozkazACK(char c);
Czyli wysłanie rozkazu (w ramce, którą funkcja umie poskładać) i
odebranie potwierdzenia ACK i weryfikacja. Jak się nie zgadza to wyjątek.
I potem mam takie funkcje jak:
void Rozkaz_C(){RozkazACK('C');}
void Rozkaz_z(){RozkazACK('z');}
itd.
wszystko zapisane tylko w pliku h.
Quote:
Nowe C++ mają interesujace metody inicjacji struktur, może warto
zainteresować się własnie dlatego standardami C++xx. Jedna już Ci
pokazałem: { 10, 20 } konstruje strukturę z dwoma intami, jesli
występuje w kontekscie, gdzie takie coś jest sensowne.
Czyli pod jakimś nowym C++ pewnie to co próbowałem to by zadziałało.
Przed pisaniem tego posta zrobiłem próby i przygotowałem sobie (na
drugim komputerze) plik do pokazania co dokładnie mi nie działało.
To jest cała treść pliku cpp:
--------------------------------
#include <windows.h>
GUID g= {0x00112233,
0x4455,0x6677,{0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}};
void fun(GUID g);
void fm()
{
fun(g);
fun({0x00112233,
0x4455,0x6677,{0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}});
}
-------------------------------------
Drugiego wywołania funkcji fun Builder 5 nie akceptuje.
Próbowałem dawać dodatkowe nawiasy i nic.
Mój problem rozwiązało by też jakbym potrafił przekonwertować ciąg
bajtów na GUID, bo ciąg bajtów daje się wpisać jak łańcuch.
Ale o ile się nie mylę to też mi to nie wychodziło jakoś prosto. Z tego
komentarza co sobie napisałem wynika, że jakoś problem dawał się
rozwiązać ale było bardziej zagmatwane niż deklaracje zmiennej GUID i
jej użycie i dlatego tak to powpisywałem.
A teraz miałem nadzieję, że jednak się jakoś da.
Czyli wygląda, że usiłowałem uzyskać coś co nowsze już umieją.
Możliwe, że teraz jak już (od niedawna) jestem pod Windows 10 z którym
Builder 2010 się nie gryzie to mogę się stopniowo przenieść pod niego.
Mimo, że to 2010 a kolejne wersje C++ zaczynają się od 11 to kto wie
mogli coś tam zrobić sami z siebie a potem zostało to wciągnięte w standard.
P.G.
heby
Guest
Mon Jul 25, 2022 7:29 pm
On 25/07/2022 20:40, Piotr Gałka wrote:
Quote:
Dla Ciebie 'zysk' to jakieś oszczędności pamięci lub czasu realizacji.
Tak, to w końcu embedded, każdy bajt sie liczy.
Już co najmniej kilka razy przewinęła się informacja, że ja pod
Builderem, a nie embedded.
To Cie nie usprawiedliwia

Już w wątku narzekano na Javę, że taka
spasła...
Quote:
To troche stoi w poprzek koncepcji hermetyzacji. Skogo GUID jest
specyficzny dla konkretnej implemetacji klasy, składanie ich w jednym
plików jest nierozsądne, nie powinny wiedzieć o swoim istnieniu.
Od strony embedded - oczywiście masz rację. To są osobne urządzenia i
nic jednemu do drugiego.
Ale ja piszę o moim programie komunikującym się z nimi.
To akuratnie źle od embedded i od PC.
Quote:
Mi pasuje jak tabelki umiące wyszukiwać urządzenia o poszczególnych
GUIDach są zdefiniowane w jednym pliku.
Architekturę zrobiłbym zupełnie odwrotnie, tzn moduły rejestrowały by do
tabelki co mają.
Quote:
Być może template miałoby tu faktycznie sens żeby do programu weszły
tylko te wersje faktycznie użyte, ale jak poszczególne klasy to tylko
inny konstruktor i być może (zapisany w h) robiony z automatu jako inline.
Niekoniecznie. Templates tutaj miały by sens, gdybyć chciał zyskać
jakies bajty w RAM kosztem bajtów Flash itp machloje. W przypadku
programowania PC nie ma to znaczenia i robisz, jak Ci wygodnie, choc
oczywiście złośliwy by się czepiał że nie prawilnie.
Quote:
O ile pamiętam w pliku cpp też mogę użyć słowa inline (nigdy nie
użyłem), które dla kompilatora jest jedynie wskazówką.
To ma wtedy ograniczone znaczenie w tym pliku i jest mało uzyteczne -
kompialtor i tak inlineuje funkcje, któe uzna i nie inlineuje, nawet
tych oznaczonych, jesli mu się nie spodobają. To takie samo słowo jak
"register" w C, obecnie bez sensu.
Quote:
GUID g= {0x00112233,
0x4455,0x6677,{0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}};
void fun(GUID g);
void fm()
{
fun(g);
fun({0x00112233,
0x4455,0x6677,{0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}});
}
Drugiego wywołania funkcji fun Builder 5 nie akceptuje.
Próbowałem dawać dodatkowe nawiasy i nic.
void fun(GUID const& g);
fun( GUID(0x100,0x100,...) ); ?
Quote:
A teraz miałem nadzieję, że jednak się jakoś da.
Się da, ale nie wiem czy Builder nie ma jakiś problemów. Kiedy w nim
pisałem, 20 lat temu, miał masę problemów z C++.
Quote:
Czyli wygląda, że usiłowałem uzyskać coś co nowsze już umieją.
Możliwe, że teraz jak już (od niedawna) jestem pod Windows 10 z którym
Builder 2010 się nie gryzie to mogę się stopniowo przenieść pod niego.
Mimo, że to 2010 a kolejne wersje C++ zaczynają się od 11 to kto wie
mogli coś tam zrobić sami z siebie a potem zostało to wciągnięte w
standard.
Wątpie. Builder nigdy nie był specjalnie nowoczesny.
Piotr GaĹka
Guest
Tue Jul 26, 2022 11:53 am
W dniu 2022-07-25 o 21:29, heby pisze:
Quote:
Architekturę zrobiłbym zupełnie odwrotnie, tzn moduły rejestrowały by do
tabelki co mają.
Tak mi było dla mnie naturalnie.
Jak wyszukuję według GUID i jest ich kilka to zakładam, że przyszły
użytkownik tego kodu (czyli ja za ileś tam lat) w takiej sytuacji będzie
musiał np wypisać na ekranie numery urządzeń i zapytać użytkownika o
które urządzenie mu chodzi. Czyli już w momencie wyszukiwania jest mi
potrzebna tabelka.
Jeśli chciałbym mieć tabelkę wszystkich, które w danej aplikacji w sumie
używam to wtedy byłaby to tabelka do której wszyscy zgłaszają co używają.
Quote:
fun({0x00112233,
0x4455,0x6677,{0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}});
}
Drugiego wywołania funkcji fun Builder 5 nie akceptuje.
Próbowałem dawać dodatkowe nawiasy i nic.
void fun(GUID const& g);
fun( GUID(0x100,0x100,...) ); ?
Wstawiłem ten const&, żeby nie było, że kombinuję inaczej.
Żadna z poniższych kombinacji nie przechodzi:
fun(GUID{0x00112233,0x4455,0x6677,{0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}});
fun(GUID(0x00112233,0x4455,0x6677,{0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}));
fun(GUID(0x00112233,0x4455,0x6677,(0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF)));
fun(GUID(0x00112233,0x4455,0x6677,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF));
fun(GUID(0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF));
W obu ostatnich przypadkach: Error: Cannot cast from 'int' to '_GUID'.
To są wszystko próby jakie ja już te 5+ lat temu robiłem.
Ale właśnie sprawdziłem, że takie coś przechodzi:
unsigned int a=0x00112233;
unsigned short b=0x4455;
unsigned short c=0x6677;
unsigned char d[8]={0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
GUID g= {a,b,c,{d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]}};
Dlaczego ten dziadowski GUID, który w sumie jest przecież ciągiem
bajtów, jest definiowany w taki dziwny sposób to dla mnie zagadka.
Pamiętam, że wtedy próbowałem podawać dane inaczej (może jest inny
konstruktor), ale nie trafiłem w nic sensownego.
To w sumie oznacza, że mógłbym jako parametr konstruktora podać ciąg
bajtów zapisany jako łańcuch (bo inaczej to chyba nie da się (w moim
Builderze) wpisać od razu w linijce).
W konstruktorze klasy bazowej musiałbym to korzystając z tej metody
zamienić na GUID i przypisać tę wartość zmiennej w tej klasie bazowej
(ale raczej po prostu GUID a nie referencji do GUID).
A może bardziej zgodne z defaultową postacią zapisu tych GUID będzie
jakby konstruktorowi klasy bazowej dać 4 zmienne (dword,word,word,byte*).
Zakładam, że da się wpisać (byte*)".....". Jak nie to ostatni parametr
char*.
byte, word, dword to moje typedef stosowane we wszystkich programach.
To chyba jest metoda, aby uzyskać mniej więcej to co chciałem.
Sprawdzę jak zadziała i może przerobię wszystko, co w tym temacie mam
napisane, ale zdecydowanie nie teraz.
Quote:
Wątpie. Builder nigdy nie był specjalnie nowoczesny
Możliwe, ale chodzi mi po głowie, że jakieś rzeczy, które oni wcześniej
zrobili widziałem gdzieś jako nowość w C++11.
Nie pamiętam o co chodziło - po prostu zapamiętałem zdziwienie, że
czytam, że coś jest nowe, gdy ja to już od dawna znam.
P.G.
Piotr GaĹka
Guest
Tue Jul 26, 2022 12:16 pm
W dniu 2022-07-26 o 13:53, Piotr Gałka pisze:
Quote:
jakby konstruktorowi klasy bazowej dać 4 zmienne (dword,word,word,byte*).
A może zamiast byte* jednak dać tam 8 pojedynczych bajtów.
Po co oszczędzać na liczbie parametrów - powinny wylądować ciurkiem na
stosie. Ale komputer 64 bitowy obrabiając bajty chyba dużo kombinuje.
Zaczynam się skłaniać do podania 4 liczb dword.
Ale i tak będę musiał z tego powydzielać bajty do tej nieszczęsnej
definicji GUID czyli i tak robotę z pojedynczymi bajtami mu zapewnię to
może jednak zostawić tak, aby wyglądało podobnie do standardu - czyli
(dword,word,word,byte,byte,byte,byte,byte,byte,byte,byte).
P.G.
heby
Guest
Tue Jul 26, 2022 12:55 pm
On 26/07/2022 13:53, Piotr Gałka wrote:
Quote:
W obu ostatnich przypadkach: Error: Cannot cast from 'int' to '_GUID'.
Jesteś pewny tego "_" ?
Ogólnie kod zachowuje sie, jak gdyby GUID nie miał konstruktora
przyjmującego cokolwiek, poza konstruktorem kopiującym, stworzonym
automatycznie.
Piotr GaĹka
Guest
Tue Jul 26, 2022 6:05 pm
W dniu 2022-07-26 o 14:55, heby pisze:
Quote:
On 26/07/2022 13:53, Piotr Gałka wrote:
W obu ostatnich przypadkach: Error: Cannot cast from 'int' to '_GUID'.
Jesteś pewny tego "_" ?
Taki jest komunikat.
Ogólnie to chyba kiedyś dawno czytałem, że Builder do wielu
identyfikatorów dodaje sobie z przodu '_'. Być może to było jak kiedyś
mi coś pisałeś jak zrobić bibliotekę. Może wtedy się okazywało, że jak
ja nazywam jakąś funkcję ala to ona przez innych musi być wołana jako
_ala. Było jakieś uzasadnienie, ale nie pamiętam.
A może ten GUID to jakieś makro i tak faktycznie głębiej jest _GUID a
kompilator po rozwinięciu makr zna już tylko _GUID.
Quote:
Ogólnie kod zachowuje sie, jak gdyby GUID nie miał konstruktora
przyjmującego cokolwiek, poza konstruktorem kopiującym, stworzonym
automatycznie.
Ja zakładałem, że to raczej struktura niż klasa, tylko, że w C++ to się
prawie niczym nie różni. Nie chciało mi się szukać po windows.h bo to
jest zazwyczaj mało czytelne dla mnie.
Ale skoro mogę wpisać
GUID{dword,word,word{byte,byte,byte,byte,byte,byte,byte,byte}} to
pasowało by chyba do struct zawierającej te dane w takich rozmiarach i
takiej kolejności, a kopiowanie dla struktur to nawet w C było jak w
ogóle słowo konstruktor w odniesieniu do języka nie istniało dla mnie.
P.G.
Piotr GaĹka
Guest
Thu Jul 28, 2022 8:55 pm
W dniu 2022-07-21 o 16:41, heby pisze:
Quote:
Na razie o ile wiem to według brata przykład USB na załatwienie
prostej rzeczy zabiera 10x za dużo miejsca i nie zostaje miejsca na
naszą aplikację, a chcemy się zmieścić w 1/2 flasha z powodu upgrade'ów.
Gcc ma flagę -Os? Symbole debugowe wyłaczone w docelowej binarce?
Raczej nie dam wiary, że jest tak źle. Prosty kod usb UARTa na STM32
zajmował jakies kilobajty. Ba, w małym AVR potrafili to zmieścić, z
softwareową emulacją.
Odgrzebię starą wypowiedź bo małe! co nieco mogę powiedzieć.
Z tą objętością to pewnie przesadziłem.
Nie wiem co to flaga -0s
Make ostatnio używałem z Turbo C++ 1.0 w okolicy 1990. Od tamtej pory
używam po prostu środowiska więc nie znam żadnych flag.
Dziś brat trochę mi opowiedział o tym przykładzie USB który ma z jakimś
ich systemem uruchomieniowym. To jest przykład, ale to wygląda jakby
stosowany zestaw funkcji miał być (według słów brata olbrzymią)
biblioteką do obsługi USB w tych procesorach.
To co mogę powiedzieć jest trochę jak głuchy telefon bo wiem, że choć ma
się jakieś wyrobione zdanie trudno jest czasami wszystko wyłożyć komuś
(czyli mi) kto nie zna szczegółów. Mówi się wtedy tylko o prostych
najważniejszych rzeczach i wiele szczegółów ginie.
Mówił mniej więcej tak:
Jakoś w końcu udało mi się przebić przez ten przykład. Wreszcie mi to
zadziałało - urządzenie zgłasza się jako nasze. Tylko tyle tam mi śmieci
zostało z tego co oni napisali...
Nie uwierzysz jak idiotycznie to jest napisane. Po pierwsze wszystko
robią w przerwaniach. Kto to widział. Przerwanie powinno być krótkie, a
nie że jak się zaczyna to końca nie widać. Całe ramki analizują w
przerwaniach. Na dokładkę na cały czas przerwania blokują wszystkie
inne. No jak takie coś ma potem w ogóle działać.
Jest taki endpoint kontrolny do którego przychodzą tylko ramki
sterujące. Jest ramka z danymi z którymi trzeba coś zrobić i jest ramka
na którą ja mam odpowiedzieć. Jak odpowiem to mam dostać potwierdzenie w
postaci pustej ramki. Wyobraź sobie, że oni jak wyślą te dane to
przestawiają cały endpoint kontrolny na odbiór zwykłych ramek (a
przecież do enpointa kontrolnego takie ramki nie mogą w ogóle trafiać) i
w ten sposób odbierają tę pustą ramkę i potem znowu przestawiają
wszystko na odbiór ramek sterujących bo może taka się zdarzy.
Zapytałem, a czy muszą się przestawiać:
Nie w życiu. Tę pustą ramkę swobodnie odbieram bez przestawiania
czegokolwiek. Program jest tak pisany jakby było wiadomo, że teraz ma
przyjść akurat ta pusta ramka. A jak nie dotrze to będzie to wisiało bo
się nie przestawi na ramki sterujące. Przecież tak nie może program
wyglądać. I potem ktoś się wzoruje na czymś takim i mamy jak mamy.
Ja: Jak przestawiony na normalne to kontrolnych nie odbierze?
Nie odbierze.
To był trochę przycinek do mnie, bo moje programy na PC komunikujące się
z naszymi urządzeniami ja tak piszę, że czekam na to co wiem, że ma
przyjść i jak jest coś innego to wywalam błąd. Brat w ogóle nie
akceptuje takiego podejścia i nie omieszka mi tego zawsze wytknąć.
Podobno ratuje mnie tylko to, że moje programiki to są do prostych
operacji z naszymi urządzeniami i jak się coś wysypie to można
powtórzyć. Ale ja uważam, że skoro ja rządzę na łączu to mogę zakładać,
że wszyscy się podporządkują.
Według niego nie można nigdy czekać na to co się wię, że ma przyjść i
nie wiedzieć co zrobić z nieoczekiwanymi ramkami i co zrobić jak się nie
doczekamy (ja w niektórych sytuacjach je celowo gubię i czekam (z
timeoutem) na tę jedną jedyną co wiem, że ma przyjść).
Zawsze trzeba być przygotowanym na wszystko bo może na łącze dostanie
się wcześniej jakaś inna ramka.
To jego podejście chyba głównie jest kopiowaniem podejścia z RS485 gdzie
kompletnie nie wiadomo co przyjdzie, czy do mnie, czy w ogóle inni
rozmawiają, czy może zderzenie ramek. I urządzenie ma w każdej chwili
wiedzieć (czyli tyle co przerwanie na zbocze - a w sensie całej szyny
RS485 najdalej po czasie propagacji zbocza - około 10us), że linia jest
zajęta i jak się ma chęć coś nadać to trzeba poczekać na koniec czyjejś
transmisji.
To wynika z tego, że my na RS485 nie stosujemy odpytywania tylko każdy,
kto coś ma do nadania nadaje. Informacje są przekazywane prawie
najszybciej jak się da. Minimalne przerwy na łączu wynikają z dodawania
losowych opóźnień aby jak dwaj wejdą na raz to przy następnym razie już
jeden był wcześniej od drugiego.
P.G.
Goto page Previous 1, 2, 3 ... 22, 23, 24