Sziasztok!
A következőt szerettem volna megcsinálni. Létrehoztam egy saját típust:
typedef unsigned char ColorRGB[3];
majd alap színeket készítettem:
ColorRGB black = {0x00,0x00,0x00};
ColorRGB white = {0xff,0xff,0xff};
ColorRGB red = {0xff,0x00,0x00};
ColorRGB orange= {0xff,0xa5,0x00};
ezt követte egy struktúra deklaráció, amiben használnám is ezt:
struct ciphers_name
{
unsigned char *name;
unsigned char *description;
ColorRGB color;
};
Eddig minden rendben is van, de szeretnék alap adatokat bele is tölteni, de nem tudom, hogyan hivatkozhatnék az orange, red...stb színeimre, hogy a struktúrába betöltse:
struct ciphers_name ciphers[] =
{
{ "aes128cbc","AES 128bit CBC",orange},
{ NULL,NULL,red},
};
Tehát a kérdésem az lenne, hogyan tudom ezt megoldani, hogyan tudom a színeimet használni a struktúrában, amikor feltöltöm?
/Mivel valószínűleg az első válasz azt fogja mondani, hogy a struktúrában a ColorRGB *color -ként deklaráljam, majd feltöltéskor &orange -ot használjak, ha így lenne, akkor egy printf -et is kérnék, hogyan tudom kiiratni:
printf ("COLOR: %06X\n",??ciphers[0].color??
mivel ezt a változatot is kipróbáltam, de ilyenkor nem nagyon tudom, hogyan férek hozzá az értékhez ami az orange -ban van/
- 1655 megtekintés
Hozzászólások
A példádban orange egy tömb, tehát a neve a tömb első elemére mutató pointer. Ezért így biztosan nem működik.
Ha a structban a color mondjuk unsigned char* lenne, akkor annak értékül adhatnád az orange-t, úgy ahogy írtad. Persze ilyenkor csak az előre definiált színeket használhatod, hiszen a struct-ban nincs hely 3 unsigned char-nak, csak egy pointer.
Ebben az esetben chipers[0].color[0] megadja az első elemét a színnek, chipers[0].color[1] a másodikat, stb.
Sajnos marha régen programoztam C-ben, ezért kéretik a fentebb írtakat kipróbálni!
KisKresz
- A hozzászóláshoz be kell jelentkezni
1. változók helyett define-ket használsz:
#define orange { 0x1, 0x2, 0x3}
struct ciphers_name ciphers[] =
{
{ "aes128cbc","AES 128bit CBC",orange},
{ NULL,NULL,red},
};
2. ahogy mondtad, pointert használsz:
#define COLOR_TO_INT(x) (x[0] | (x[1] << 8) | (x[2] << 16))
printf ("COLOR: %06X\n", COLOR_TO_INT((*ciphers[0].color)));
vigyázz a dupla zárójelre...
- A hozzászóláshoz be kell jelentkezni
vagy ezt inkább a makróban:
#define COLOR_TO_INT(x) ((x)[0] | ((x)[1] << 8) | ((x)[2] << 16))
- A hozzászóláshoz be kell jelentkezni
Persze nekem az is jó lenne, ha nem ragaszkodnék a saját típusomhoz, így megúsznám a tömböt. Az alap-alap probléma ahogy a neve is mutatja a színek RGB tárolása. Mivel nincs 3bájt méretű típus ezért csináltam egyet Egyszerűbb lenne, ha mondjuk unsigned int -et használnék, de kérdés, hogyan tudom bájt szinten az adatokat kiszedni belőle. Egyáltalán ki lehet úgy szedni ahogy én szeretném.
Tehát van egy unsigned int aminek az értéke: 0xABCDEF
Ebből kellene nekem külön a 0xAB, 0xCD, 0xEF. int -et szét lehet így szedni? ha igen, akkor ez egyszerűbb megoldás mint amit első körben kitaláltam.
Ha jól gondolom az unsigned int 4bájtos, ha bele rakom a 0xABCDEF értéket akkor a 4bájt értéke 0x00 0xAB 0xCD 0xEF lesz. hogyan lehet egy int bájtjaira hivatkozni?
- A hozzászóláshoz be kell jelentkezni
unsigned int color;
color & 0xff -> szin 1
(color >> 8) & 0xff -> szin2
(color >> 16) & 0xff -> szin3
rtfm c manual?
- A hozzászóláshoz be kell jelentkezni
amúgy hiába csinálsz 3 byteos struktot, úgyis 4 bytera alignolja a fordító... hacsak meg nem adod neki explicit hogy ne tegye...
- A hozzászóláshoz be kell jelentkezni
x86, alpha, amd64, ppc, stb - mindenhol?
- A hozzászóláshoz be kell jelentkezni
köszi! ez így egy nagyon triviális megoldássá vált szerencsére a problémámra.
- A hozzászóláshoz be kell jelentkezni
>> Ha jól gondolom az unsigned int 4bájtos
nem, az unsigned int az sizeof(unsigned int) bájtos
- A hozzászóláshoz be kell jelentkezni
http://www.phim.unibe.ch/comp_doc/c_manual/C/CONCEPT/data_types.html
én itt néztem, eszerint a táblázat szerint az unsigned int az 4bájtos
- A hozzászóláshoz be kell jelentkezni
ez milyen architekturara is ervenyes? :-)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
nekem a sizeof is 4-et mond
- A hozzászóláshoz be kell jelentkezni
de milyen architekturan? :-)
ez itt a lenyeg
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
Mivel most eppen aktualis a tema, eppen az elobb futottam bele egy kollega ilyen deklaraciojaba:
typedef long int __int64;
most figyelj:
sizeof(long int) erteke 4
Ez egy qrva nagy bug.
Ha mar mindenaron definialt egy __int64 -et (raadasul elojel nelkul kellett volna), akkor azt igy kellett volna:
typedef uint64_t __int64;
elojelesen pedig:
typedef int64_t __int64;
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
igaz...
a long int nem garantál semmit. A c csak annyit köt meg, hogy sizeof(short) <= sizeof(int) <= sizeof(long).
Vigyázni kell amikor az ember portabilis kódot akar írni. Mert pl. egy x86-64 rendszeren a unixoknál de facto szabvány, hogy a longban elfér a pointer, i.e. 8 byteos. De ugyanezt MS-ék nem tudták megcsinálni, win64 alatt visual c++ban a long is csak 4 byteos.
Szóval ha portabilis kódot akar az ember írni, akkor használja a saját típusait, amiket a platform szerint egy helyen definiál meg.
Amúgy az __int64 beépített típus vc++ban.
- A hozzászóláshoz be kell jelentkezni
"Amúgy az __int64 beépített típus vc++ban."
Igen, az stimmel, csak ez unix volt, tovabba:
1. erosen platformfuggo deklaracio
2. 0-rol indulo szamlalokat deklaralt vele
3. 8 byte-os tartomany kovetelmeny
4. ciklust (2^64-1) -ig kuldte 0-rol nem pedig sizeof(__int64) vagy ha mar rosszul elojelesnek definialta, akkor legfeljebb a feleig (lefele kerekitve) illett volna
5. sikogatott, hogy mar ket napja megy es nem vegeznek a ciklusok /*no comment*/
megcsinalta vele a mai napomat ezert is postoltam be :-O
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
hát... ezek szerint van gond... :)
p.s.: nem volt php-s az illető előtte? :D
- A hozzászóláshoz be kell jelentkezni
lol
ezt nem tudom, de vb-t meg clippert mar latott
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
... jó ember már nem lehet. :))
- A hozzászóláshoz be kell jelentkezni
haaat... van baja... :D
egyebkent korabban is csinalt mar hasonlo melyszantasokat, meg is duplaztattam a haziorvosommal a napi Artrotec adagomat
azt most latom, hogy a fenti listarol lemaradt, hogy a 2^64-et a ciklus minden feltetelvizsgalatakor ujraszamoltatta szerencsetlennel
bar, jo fej, meg akarat van benne, ugyh barmi lehet meg belole, bizonyitani akar, csak meg nagyon suttyo es kapkod
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
Jé, az stdint.h-ban pont ezek vannak deklarálva :) !
...
#ifndef __int8_t_defined
# define __int8_t_defined
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
# if __WORDSIZE == 64
typedef long int int64_t;
# else
__extension__
typedef long long int int64_t;
# endif
#endif
stb.
- A hozzászóláshoz be kell jelentkezni
Igen, lentebb (vagy fentebb) mar irtam is korabban, hogy ezek nem platform fuggok, erosen ajanlott hasznalni oket ha a valtozo altal foglalt meret a lenyeges. :)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
hát ha a nagy internetbe' is megírták, akkor csakis úgy lehet
(főleg, ha az egy felsőoktatási intézmény lapja:))
- A hozzászóláshoz be kell jelentkezni
"Ha jól gondolom az unsigned int 4bájtos"
ha pontosan akarod definialni egy integer meretet akkor celszeru betolteni az "stdint.h"-t, majd a meret alapjan szabvanyos tipusokat hasznalni. (Pl: uint8_t, uint16_t, uint32_t, ....)
Ugyanez mehet az elojelesekre is (Pl: int8_t, int16_t, int32_t, ....)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
Lenne még kérdésem, de nem akarok új fórumtémát nyitni ennek is.
Hogyan lehet függvényt úgy deklarálni, hogy paraméterként függvényt lehessen neki átadni?
do_it (????)
{
f(arg);
}
int
main()
{
//és mondjuk az strcpy függvényt szeretném átküldeni + a hozzá tartozó src és dst paraméterét
do_it(???);
}
- A hozzászóláshoz be kell jelentkezni
van ilyen, hogy pointer függvényre...,
itt le van írva...
Bruce Eckel: Thinking in C
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html
- A hozzászóláshoz be kell jelentkezni
én csak C++ -t találok
- A hozzászóláshoz be kell jelentkezni
Amit lentebb irtam neked az "C"-ben van megirva :-)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
ja.. igen, nézem. itt van igen:
void glutReshapeFunc(void(*func)(int width, int height));
{
}
static void
reshape(int width, int height)
{
}
int
main()
{
glutReshapeFunc(reshape);
}
bár az az egy még nem világos, hogy a függvény paraméterei hogy kerülnek át, mert itt bár a shape rendelkezik paraméterrel, de amikor glutReshapeFunc(reshape); hívja akkor nincs paramétere.
majd kipróbálom aztán már okosabb leszek. ha meg nem, akkor írok :-)
köszi!
- A hozzászóláshoz be kell jelentkezni
Igen, ez lesz az. ;-)
Felesleges atadni benne a parametert, hiszen itt csak az altalad definialt "reshape" vagy akarmilyen nevu fuggveny cimet kuldod be a glutba. A lenyeg csak az, hogy a kovetkezo egyezzen:
void glutReshapeFunc(void(*func)(int width, int height));
void reshape(int width, int height)
Adhatsz te annak static void mikieger(int width, int height) nevet is ha ugy tetszik, mivel csak a cimet passzolja at. ;-)
Szerk: azt elfelejtettem mondani, hogy itt a C-ben a valtozok ertekei "masolodnak" nem mint pl a pascalnal, fortran-nal, stb ahol a cimeik vannak "atiranyitgatva" jobbra-balra.
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
értem én, hogy a cím megy át, de ha van paramétere is mint itt a width és a height azt honnan szerzi? vagy az hogyan?? ezt nem vágom
- A hozzászóláshoz be kell jelentkezni
typedef void (*func) (int, int); // a func itt egy (int,int) szignatúrájú függvényre mutató pointer típus
void glutReshapeFunc(func F);
{
F(1,2);
}
static void
reshape(int width, int height)
{}
int
main()
{
glutReshapeFunc(reshape);
}
--
valahogy így.. talán érthetőbb.
- A hozzászóláshoz be kell jelentkezni
"typedef void (*func) (int, int);
void glutReshapeFunc(func F);
Most mar emlekszem en is, anno igy csinaltam. Amugy a C-ben callback-nek hivjak. :)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
Még annyit hadd kérdezzek már, hogy ez a forrásban talált függvény mit vár pontosan?
static double
time_function(void (*f)(void *arg), void *arg)
{
.....
do
{
f(arg);
...
}
....
}
- A hozzászóláshoz be kell jelentkezni
egy (void*) argumentumú függvényt, és a hozzá tartozó void* argumentumot, pl.:
void
func(void* x)
{}
int
main()
{
void* y;
time_function(func, y);
}
- A hozzászóláshoz be kell jelentkezni
Azt akkor adod at neki, mikor meghivod abbol a fuggvenybol, aminek parametere. Amire te gondolsz, az C/C++-ban nemigen letezik, mas helyen altalaban closure-nek hivjak. Ha nem, akkor a negy sor meg 2 deci whiksey beszel belolem :) Ez esetben bocs...
- A hozzászóláshoz be kell jelentkezni
szóval... mivel a C++ nyelv elvileg supersetje a C nyelvnek, ezért C++ban is pontosan úgy működik a függvényekre mutató pointer mint C-ben.
Namármost, nagyon szépen le van írva, ha megnézed annál a címnél, hogy "Function addresses" hogy mi is az a fuggvényre mutató pointer, utána pedig a komplex deklarációk/definíciókkal mit is kell kezdeni.
- A hozzászóláshoz be kell jelentkezni
Regen csinaltam mar ilyet, de most be nem ugrik. Valami olyasmi volt, hogy kellett definialni egy ugyanolyan parameterekkel rendelkezo fuggvenyt, majd a cimet atadni argumentumban.
Pl:Most hirtelen ami beugrik, a glut az ami igy kezeli a kulso callbackeket. Nezzel bele az glut-ba es keress ra az eger/billentyuzet esemenyek fuggvenyeinek deklaraciojara.
Van itt egy rovid peldaprogram is ami alapjan el tudsz indulni. (neha szakadozik a netem, ha nem elerheto, nezd meg kesobb)
http://my-cat-is-a.dyn-o-saur.com/hosted/gears.c
Ezek a reszek lesznek szamodra erdekesek:
[...]
glutDisplayFunc(draw);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutVisibilityFunc(visible);
[...]
Ezek adjak at a glutnak a kulso fuggvenyek cimeit, azt meg, hogy a glut, hogyan hivja meg oket, ki tudod lesni a glut forraskodjabol. :-)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
Kozben mig irtam kaptal is ujabb valaszt. :-)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
már megint belefutottam olyanba, ami meghaladja szerényke C tudásomat:
az openssl -t használnám jobban mondva annak az EVP-s függvényeit. működik is minden szépen, viszont van egy EVP_EncryptInit függvény melynek 2.paramétere egy const EVP_CIPHER *type mely a /usr/include/openssl/evp.h ban van leírva.
pl:
const EVP_CIPHER *EVP_aes_128_ecb(void);
const EVP_CIPHER *EVP_aes_128_cbc(void);
const EVP_CIPHER *EVP_aes_128_cfb1(void);
const EVP_CIPHER *EVP_aes_128_cfb8(void);
const EVP_CIPHER *EVP_aes_128_cfb128(void);
EVP_EncryptInit leírása:
int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char *key, unsigned char *iv);
A következő képpen használva:
EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, NULL);
nagyon szépen csinálja is a dolgát. viszont sokkal egyszerűbb lenne az életem, ha egy függvényt írnék ami paraméterben kapná az infókat, amivel meghívja ezt az EVP_EncryptInit -et. Viszont ehhez tudnom kéne, hogyan tudom átadni ezt a bizonyos const EVP_CIPHER *type -t. Ami eddig még nem ment sajnos.
1. a struktúrámba szeretném felvenni ezt a pluszt, de nem tudom hogyan kellene:
struct ciphers_name
{
unsigned char *name;
unsigned char *description;
EVP_CIPHER *func;
ColorRGB color;
};
2. amikor inicializálom az adatokat, akkor megint csak nem tudom, hogyan tudom beletölteni a helyes értékeket:
struct ciphers_name ciphers[] =
{
{ "aes128cbc","AES 128bit CBC",EVP_aes_128_cbc(),orange}
};
3. ha már ezek rendben vannak, akkor hogyan tudom deklarálni a függvényemet, melyet különböző EVP_CIPHER -rel tudok meghívni?
do_encrypt(const byte* key, byte* intext, int inlen, byte* outbuf, int* outlen, EVP_CIPHER *f;)
{
EVP_EncryptInit(&ctx, f(), key, NULL);
}
remélem ebben is tud valaki segíteni, előre is köszönöm!
- A hozzászóláshoz be kell jelentkezni
Az a fura, hogy ha az elején NULL értéket adok:
struct ciphers_name ciphers[] =
{
{ "aes128cbc","AES 128bit CBC",NULL,orange}
};
majd később:
ciphers[0].cipher = EVP_aes_128_cbc();
akkor simán jó.
ha az elején próbálom ezt:
struct ciphers_name ciphers[] =
{
{ "aes128cbc","AES 128bit CBC",EVP_aes_128_cbc(),orange}
};
akkor meg kapom a hibaüzenetet:
gcc -Wall -O2 evp.c -o evp -lssl
evp.c:23: error: initializer element is not constant
evp.c:23: error: (near initialization for `ciphers[0].cipher')
evp.c:23: error: initializer element is not constant
evp.c:23: error: (near initialization for `ciphers[0]')
- A hozzászóláshoz be kell jelentkezni
A választ közben megkaptam az openssl levlistán, ha valakit érdekel berakom ide.
- A hozzászóláshoz be kell jelentkezni
egy dinamikus tömb esetén hogyan lehet lekérdezni, hogy hány eleme van a program futása közben? főleg ha struktúra.
struct akarmi tomb[] = {
{"x", 0, "y",1},
{"a",1,"z",6},
};
tehát itt ugye van tomb[0] és tomb[1] vagyis 2db. ezt meg lehet valahogy tudni?
- A hozzászóláshoz be kell jelentkezni
az ilyen tömb pont nem dinamikusan változó méretű, úgyhogy:
sizeof tomb/sizeof(struct akarmi) == 2
- A hozzászóláshoz be kell jelentkezni
köszönöm!
- A hozzászóláshoz be kell jelentkezni