Löst: Cast pointer, ansi c

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Xyzzy
Inlägg: 1222
Blev medlem: 30 januari 2004, 22:31:07
Ort: Uppsala, Sweden

Löst: Cast pointer, ansi c

Inlägg av Xyzzy »

Hej,

Garanterat en enkel fråga för er, men min mjukvarukunnande är för klent och min google-fu är inte med mig idag.

SDKt har en funktion som är definierad likt:

Kod: Markera allt

void foo(uint8_t * data){
...
}
Och kan inte ändras.

Jag har idag dessa rader i min kod:

Kod: Markera allt

  uint8_t buffer[5];
  ...
  buffer[0] = 0x03;
  foo(buffer);
...
Dock vill jag ändra anropet till liknande:

Kod: Markera allt

  foo(0x03);
mest för att minska på raderna i koden, dvs göra allt lite renare då detta anropet behöver göras många gånger i slutgiltiga koden.

Kompilator jag behöver använda är sdcc (under Linux).
Detta ska köras på en nRF24LE1.

Hur ska raden ändras i understa code-taggen ändras för att fungera?
Eller går det inte till ett fixt värde endast till variabler?

Mvh,
Erik.

Edit, uppdaterade ämnet med löst.
Senast redigerad av Xyzzy 17 november 2016, 11:49:59, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26147
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Cast pointer, ansi c

Inlägg av Icecap »

Funktionen kräver en pekare till en uint8_t - det kan du inte ändra.

MEN - du kan skapa en uint8_t constant som innehåller 0x03 och skicka pekningen till den.

const uint8_t <ett vettigt namn> = 0x03;

foo(<ett vettigt namn>);
Användarvisningsbild
Xyzzy
Inlägg: 1222
Blev medlem: 30 januari 2004, 22:31:07
Ort: Uppsala, Sweden

Löst: Re: Cast pointer, ansi c

Inlägg av Xyzzy »

Tack för ditt snabba svar!

Det är så illa alltså, typiskt.
Eftersom den kommer anropas många gånger i koden med olika värden så blir det ingen direkt vinst.
Då kör jag vidare med orginalet.

Tack för hjälpen igen.
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Löst: Cast pointer, ansi c

Inlägg av johano »

Gör en wrapper-funktion:

Kod: Markera allt

void my_foo(uint8_t u)
{
  foo(&u);
}

my_foo(0x03);
/j
Användarvisningsbild
Xyzzy
Inlägg: 1222
Blev medlem: 30 januari 2004, 22:31:07
Ort: Uppsala, Sweden

Re: Löst: Cast pointer, ansi c

Inlägg av Xyzzy »

Ahh, ja det borde ju gå iofs.
Det ska jag testa, tack för tipset, uppskattas mycket.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Löst: Cast pointer, ansi c

Inlägg av sodjan »

Med en extra call-level, så klart. Beroende på miljö kan det vara ett problem, eller inte... :-)
Eller kommer kompilatorn att "inline'a" den wrappern?
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Löst: Cast pointer, ansi c

Inlägg av lillahuset »

Jag hade definitivt gjort som Icecap föreslår. Det enklaste och naturligaste sättet.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Löst: Cast pointer, ansi c

Inlägg av Mr Andersson »

Nu är det ju redan löst, men foo((uint8_t[]){3}); fungerar också (i C99+).
En fundering jag har är hur vet SDKet hur lång arrayen är? Är det alltid bara en byte känns ju funktionen feldesignad.
Användarvisningsbild
Xyzzy
Inlägg: 1222
Blev medlem: 30 januari 2004, 22:31:07
Ort: Uppsala, Sweden

Re: Löst: Cast pointer, ansi c

Inlägg av Xyzzy »

Tack, det alternativet såg intressant ut, ska försöka sätta mig och förstå vad den innebär.

Du har helt rätt, jag slarvade när jag skrev första inlägget, foo definieras snarare som:

Kod: Markera allt

void foo(uint8_t * data, uint8_t length){
...
}
Ursäkta förvirringen.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Löst: Cast pointer, ansi c

Inlägg av Mr Andersson »

Det kallas för en compound literal. I princip ett anonymt objekt av given typ.
http://en.cppreference.com/w/c/language ... nd_literal

Aha den vill ha längd också. Då måste man komma ihåg att uppdatera längden om man ändrar datat. Det är jag expert på att glömma :D
Eller så kan man göra lite macro-tricks.

Kod: Markera allt

#include <stdint.h>
#include <stdio.h>

// dummy function to match foo's signature
void foo(uint8_t* data, uint8_t len)
{
	uint8_t i = 0;
	while (i < len)
		printf("%d ", data[i++]);
	printf("\n");
}

// Lite fulhacks.. Fungerar bara om sizeof(char) == sizeof(uint8_t) 
// vilket är väldigt vanligt men inte garanterat.
#define CALL_FOO(...)	foo((uint8_t[]){__VA_ARGS__}, sizeof((uint8_t[]){__VA_ARGS__}))

int main()
{
	CALL_FOO(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
}
Användarvisningsbild
Wedge
Inlägg: 1026
Blev medlem: 8 juli 2012, 17:33:33

Re: Cast pointer, ansi c

Inlägg av Wedge »

Icecap skrev:Funktionen kräver en pekare till en uint8_t - det kan du inte ändra.

MEN - du kan skapa en uint8_t constant som innehåller 0x03 och skicka pekningen till den.

const uint8_t <ett vettigt namn> = 0x03;

foo(<ett vettigt namn>);
foo( & <ett vettigt namn>); ska det i så fall vara.
Användarvisningsbild
Icecap
Inlägg: 26147
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Löst: Cast pointer, ansi c

Inlägg av Icecap »

Jeps - men nu är det ju tydligen inte nog, längden ska ju med.

const unsigned char EttVettigNamn = {0x03};

Alltså ska kommandot vara:
foo(&EttVettigtNamn, sizeof(EttVettigtNamn));

Då blir storleken automatisk uppdatering om man ändrar.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Löst: Cast pointer, ansi c

Inlägg av Mr Andersson »

Storleken kommer ju alltid vara ett då du har en char istället för array av char.
Användarvisningsbild
Icecap
Inlägg: 26147
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Löst: Cast pointer, ansi c

Inlägg av Icecap »

Nej.
const unsigned char EttVettigNamn = {0x03, 0x05, 0x08};
har sizeof() = 3;
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Löst: Cast pointer, ansi c

Inlägg av Mr Andersson »

Inte i en C-kompilator.

Kod: Markera allt

micke@uvm:~/src/test2$ cat test.c 
#include <stdio.h>
const unsigned char EttVettigtNamn = {0x03, 0x05, 0x08};

int main()
{
	printf("size %lu\n", sizeof(EttVettigtNamn));
}

micke@uvm:~/src/test2$ gcc-5 test.c && ./a.out
test.c:2:45: warning: excess elements in scalar initializer
 const unsigned char EttVettigtNamn = {0x03, 0x05, 0x08};
                                             ^
test.c:2:45: note: (near initialization for ‘EttVettigtNamn’)
test.c:2:51: warning: excess elements in scalar initializer
 const unsigned char EttVettigtNamn = {0x03, 0x05, 0x08};
                                                   ^
test.c:2:51: note: (near initialization for ‘EttVettigtNamn’)
size 1

micke@uvm:~/src/test2$ clang-3.8 test.c && ./a.out
test.c:2:45: warning: excess elements in scalar initializer
const unsigned char EttVettigtNamn = {0x03, 0x05, 0x08};
                                            ^~~~
1 warning generated.
size 1
Skriv svar