Wątek przeniesiony 2022-01-10 01:52 z Edukacja przez cerrato.

Problem z właściwym doborem typów danych przekazywanych do funkcji w C oraz prośba o linki do materiałow wyjaśniających metody łączenia C z Pythonem

0

Cześć!

Nie jestem pewny, czy w dobrym wątku ten wpis, ale myślę że jest mocno edukacyjny. Nakreślę szybko kontekst - może się uda ;)

Chodzi o to, że przez "Adminke" Linuxa'mi/Unix'ami sporo zapomniałem, jak używać C :'(. W mocnych "skill'sach" został mi raczej sam Python. Każdy doświadczony Dev wie, że Python jest wysoko-poziomowy i wszystko co w C ma 100 linii, można w Python'ie zmieścić w trzydziestu liniach :p. No ale kurde... nie samym Python'em człowiek żyje ;), w każdym razie, myślę że zrobienie czegoś w C niesie ze sobą więcej wartości edukacyjnych (oczywiście nie chce umniejszać Python'owi, ale jednak ..), niż zrobienie tego samego w wysoko poziomowym języku, szczególnie że zależy mi na dogłębnym poznaniu systemów Linux :)

Mam sporo problemów już na starcie :x, bo postawiłem sobie za cel zrobić prosty program do śledzenia zmian w plikach i zgłaszanie tego do ELK w czystym C. Problem w tym, że wykładam się na takich podstawach jak:

note: expected ‘const char **’ but argument is of type ‘const char *’

Nie rozróżniam, kiedy używać &/* podczas przekazywania argumentu funkcji .. co lepsze, zawsze jak widzę w dokumentacji, że jakaś funkcja wymaga wskaźnika(*) albo bezpośredniego wskazania miejsca w pamięci(&) to gdy przekazuje oczekiwane argumenty, to bardzo często okazuje się, że te argumenty muszą być zupełnie "odwrotne" (skrót myślowy, postaram się jutro pokazać jakieś konkretne przykłady).

Rzecz w tym, że w takich sytuacjach korci mnie, żeby zrobić to w Pythonie, ale no... to pójście na łatwiznę :). To co chciałbym osiągnąć, to napisanie tego w C i ewentualnie połączyć jakąś część wybranej funkcjonalności z Pythonem.

Pytania:

  1. Jak rozróżniać, kiedy ma być przekazywany odpowiedni argument do funkcji? wg. mnie funkcja która oczekuję wskaźnika(*), powinna otrzymać jej adres(&), wtedy dochodzi do "wyłuskania" jej wartość, pisze o tym S.Prata, ale mogę coś mylić. Dam sobie rękę uciąć, że zdarzyło mi się, że funkcja wołała o wskaźnik, ale po podaniu adresu(&) wywalał się błąd
  2. Czy znacie jakieś fajne, merytoryczne linki gdzie jest pokazane, jak łączyć Python'a z C? I nie chodzi mi o wywoływanie przy pomocy C, Pythona i na odwrót
3

Zacznę od końca:
Ad 2. "I nie chodzi mi" - no to o co Ci chodzi? ;)
Zacząłbym tu https://docs.python.org/3/library/ctypes.html
Z pythona możesz generalnie wczytać libkę dynamicznie ładowaną i używać jej symboli. Przeprowadź inżynierię wsteczną pythonowych socketów albo select.
Ale szczerze mówiąc nie wiem co dokładnie chcesz zrobić.

Ad. 1.:
Bez kodu trudno powiedzieć w czym problem, ale ogólnie komplikujesz to imho nadmiernie.
Zmienne (generalnie) mają swój adres. Operator & bierze adres, * dokonuje dereferencji, tzn. interpretuje pamięć pod danym adresem wg typu wskaźnika.
Sam wskaźnik tez może być zmienną.

int x = 3; //int z wartością 3
int* xptr = &x; //adres powyższego inta
int** pptr= &xptr; //adres, pod którym jest adres x
int y = *xptr; //nowa zmienna całkowita, zainicjowana przez odczyt inta pokazywanego przez xptr

no i teraz jak masz funkcję void f(int* arg);
to możesz przekazać do niej:

f(&x); //przekazujesz ad-hoc wzięty adres x
f(xptr); //przekazujesz zapisany w zmiennej adres x
f(*pptr); //przekazujesz zmienna wskaźnikową, na ktora pokazuje pptr
2

wg. mnie funkcja która oczekuję wskaźnika(*), powinna otrzymać jej adres(&), wtedy dochodzi do "wyłuskania" jej wartość, pisze o tym S.Prata, ale mogę coś mylić. Dam sobie rękę uciąć, że zdarzyło mi się, że funkcja wołała o wskaźnik, ale po podaniu adresu(&) wywalał się błąd

Nietrudno to uzyskac, np:

void func(const char* a) { }
char* a;
func(&a); // zle
func(a); // a juz tak dobrze
  1. Czy znacie jakieś fajne, merytoryczne linki gdzie jest pokazane, jak łączyć Python'a z C? I nie chodzi mi o wywoływanie przy pomocy C, Pythona i na odwrót

https://docs.python.org/3/extending/index.html
Piszac modul wypadaloby znac na pamiec: https://docs.python.org/3/c-api/index.html
A przyklady sa w zrodlach pythona, np: https://github.com/python/cpython/blob/main/Modules/_decimal/_decimal.c

0

@alagner: @eleventeen: wielkie dzięki za podpowiedzi. Myśle, ze faktycznie jakoś sam sobie to utrudniam :). Dzięki za linki!! Przydadzą się wszystkie !:) Na chwile obecną to musi mi wystarczyć

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