Forum: Mikrocontroller und Digitale Elektronik CANMessage: invalid conversion from 'unsigned char*' to 'const char*'


von Frank S. (mbed_rookie)


Lesenswert?

Hallo,

ich befasse mich seit 3 Wochen mit Pointern und komme jetzt an ein 
Problem, an dem ich mich ständig im Kreis drehe.

Mein Ziel ist es mit Hilfe eines RtosTimers eine CANMassege "in der 
Zukunft" zu versenden:
1
#include "mbed.h"
2
#include "rtos.h"
3
4
CANMessage msg;
5
CAN can1(p9, p10);  // rd, td
6
DigitalOut led1(LED1);
7
8
void myTest(void const *ptr) {
9
  CANMessage *ptr_msg = (CANMessage *) ptr;
10
  
11
  if (can1.write(CANMessage(ptr_msg->id, ptr_msg->data, ptr_msg->len))) {
12
// works not: invalid conversion from 'unsigned char*' to 'const char*'
13
    printf("success");
14
    led1 = !led1;
15
16
  } else {
17
    printf("failed");
18
  }
19
}
20
main...
21
  msg.id = 0x1234;
22
  msg.data[0] = 0xFF;
23
...
24
  CANMessage* ptr_msg = &msg;
25
...
26
  RtosTimer myTimer1(myTest, osTimerOnce, (void *) ptr_msg);
27
  myTimer1.start(1000);

Mir ist schon klar, dass da ein falscher Typ übergeben wird, nur tue ich 
mich schwer die richtigen Stelle zu finden bzw die richtige 
Konvertierung anzuwenden.

Während der folgende Code fehlerfrei compiliert wird,
1
  char data2[] = {0,1,2};
2
  can1.write(CANMessage(msg.id, data2, 3));   //works

scheitern die folgenden Zeilen:
1
can1.write(CANMessage(msg.id, msg.data, 3));
2
// works not: invalid conversion from 'unsigned char*' to 'const char*'
3
4
can1.write(CANMessage(111, ptr_msg->data, 3));
5
// works not: invalid conversion from 'unsigned char*' to 'const char*'

Ich sehe vor lauter Bäumen den Wald nicht mahr. Kann mir da jemand 
weiterhelfen?

Grüße,
Frank


P.S.
Später sollen mit Hilfe von Memorypool die Nachrichten hinterlegt werden 
und der Pointer zu der Nachricht vom Timer an die Sende-Funktion 
übergeben werden.
1
MemoryPool<CANMessage, 4> mpool;
2
...
3
4
  CANMessage *ptr_outgoing_msg = mpool.alloc();
5
  ptr_msg->id = 0x123;  
6
  ptr_msg->data[0] = 0x22;
7
  ptr_msg->data[1] = 0x11;
8
  RtosTimer timer(myTest, osTimerOnce, (void *) ptr_msg);
9
  timer.start(1000);
Nach erfolgreichem Versand, wird dann der Speicher wieder freigegeben:
1
mpool.free(ptr_msg);
Hier werde ich mir den Timer und seine "Lebensdauer" noch mal anschauen 
müssen (nicht, dass mir der Speicher mit lauter Timern vollläuft;))

EDIT:

Die folgende Lösung funktioniert zwar, ist aber nicht 
zufriedenstellend;):
1
  char data[ptr_msg->len];
2
  for (uint8_t i = 0; i<sizeof(data); i++) {
3
    data[i] = ptr_msg->data[i];
4
  }
5
6
  if (can1.write(CANMessage(ptr_msg->id, data, ptr_msg->len))) {...}
Geht es schneller\effizienter?

von xxx (Gast)


Lesenswert?

typecast

can1.write(CANMessage(msg.id, (const char *)msg.data, 3));

von Mark B. (markbrandis)


Lesenswert?

Vielleicht hab ich ja gerade Tomaten auf den Augen, aber ist CANMessage 
hier einmal ein Typbezeichner und einmal eine Funktion oder wie?

Hier wird eine Variable deklariert:
1
CANMessage msg;


Und hier folgt auf CANMessage der Funktionsaufruf-Operator mit drei 
Parametern:
1
if (can1.write(CANMessage(ptr_msg->id, ptr_msg->data, ptr_msg->len)))

Ist das so richtig und soll das so sein?

von Tom (Gast)


Lesenswert?

Mark B. schrieb:
> hier einmal ein Typbezeichner und einmal eine Funktion oder wie?

Konstruktor. Temporäres Objekt.


float a;
gotox(float(1));

von Tom (Gast)


Lesenswert?

Zur originalen Frage: Der Konstruktor möchte (warum auch immer) ein 
char*, den er dann in den Member unsigned char[] data memcopiert.

Wenn ich die richtige CAN.h gefunden habe, nimmt CAN.write() den 
Parameter sowieso als call by value (warum auch immer) und du kannst
can1.write(CANMessage(ptr_msg->id, ptr_msg->data, ptr_msg->len))
einfach durch
can1.write(*ptr_msg) ersetzen, ohne ein temporäres Objekt zu bauen.

von Mark B. (markbrandis)


Lesenswert?

Tom schrieb:
> Mark B. schrieb:
>> hier einmal ein Typbezeichner und einmal eine Funktion oder wie?
>
> Konstruktor. Temporäres Objekt.

Ach so. Ich war irgendwie der Meinung dass es sich um reines C handelt.

von Frank S. (mbed_rookie)


Lesenswert?

Vielen Dank,

das habe ich gesucht!

Hatte zwischenzeitlich
1
can1.write(CANMessage(ptr_msg->id,(char *)ptr_msg->data, ptr_msg->len))

als Lösung, aber:
1
can1.write(*ptr_msg);

finde ich "much sexier" ;).

Danke vielmals.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.