Jump to content

[C/C++] C Bindings und Xcode: Problem in callback Methode


Recommended Posts

Hallo,

 

ich hab ein Problem mit den C Bindings in Xcode innerhalb einer registrierten Callback Funktion für das LinearPoti Bricklet.

 

void cb_lp_position(uint16_t position) {

    [linearpoti setIntegerValue: position];

}

 

die Variable "linearpoti" (referenziert einen NSSlider) ist nur innerhalb dieser callback Methode nicht sichtbar (undeclared indentifier). Die Variable ist jedoch ordnungsgemäß definiert  und in jeder anderen Obj-C Methode sichtbar.

Hat jemand vielleicht ein Beispiel, in dem in Xcode mit Callbacks gearbeitet wird und in der Callback Methode ein GUI Objekt referenziert wird?

 

Danke vorab - kutte  :)

 

Link to comment
Share on other sites

Hallo,

 

ich benutze NSTimer:

 

timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(OnTimer:) userInfo:nil repeats:YES];

 

und

 

- (void) OnTimer:(NSTimer*)timer{
  int16_t temperatureValue;
  if (temperature_get_temperature(&temperature, &temperatureValue)<0) {
    return;
  }
  [_labelTemperature setTitle:[NSString stringWithFormat:@"% 5.2f°C", temperatureValue/100.]];

}

 

Gruß Manni

Link to comment
Share on other sites

@Manni,

 

Danke, hast Du auch schon versucht einen Callback zu Deinem Temperatur-Bricklet zu implementieren? und in der CallBack-Methode versucht z.B. ein NSTextField mit dem Wert zu füttern? Genau da (und nur da) hab ich das Problem...(wie in meinem Code-snippet angedeutet)

 

Gruss kutte

Link to comment
Share on other sites

Kann Objective C irgendwie feststellen dass der Callback aus einem anderen Thread heraus aufgerufen wird? Z.b. in Qt sind GUI Elemente nicht thread-safe und eine Änderung aus einem Callback heraus könnte sogar zu einem Segfault führen.

 

Allerdings kann das in dem Fall der Compiler natürlich nicht erkennen!

Link to comment
Share on other sites

das Problem zeigt sich bereits zur Compile-Zeit und nicht erst zur Laufzeit.

Ich habe den Verdacht, dass das generell nicht funktionieren kann, weil ich ja versuche Obj-C Referenzen in der C Umgebung (die Callback-Methode des LinearPoti) zu nutzen. Kommentiere ich die Zeile aus, kann ich kompilieren und der CallBack wird gerufen :)

linearpoti.tiff

Link to comment
Share on other sites

Erklärung:

C Funktionen sind ausserhalb der @implementation einer Objective-C (.m) Datei deklariert.

 

int MyCFunction(int num, void *data)

{

    //code here...

}

 

@implementation

 

- (void)MyObjectiveCMethod:(int)number withData:(NSData *)data

{

      //code here

}

 

@end

Da die C Funktion ausserhalb der @implementation ist, kann Sie keine Methoden aufrufen wie z.B.

 

[self doSomething]

 

und hat keinen Zugriff auf Instanz Variablen.

 

Lösung:

In der @implementation einen Zeiger definieren (refToSelf) und den Zeiger z.B. inder init() zuweisen. Nun ist im CallBack das Objekt sichtbar...

 

void * refToSelf;

int cCallback()

{

    [refToSelf someMethod:someArg];

}

 

@implementation SomeClass

- (id) init

{

    self = [super init];

    refToSelf = self;

}

- (void) someMethod:(int) someArg

{

}

Link to comment
Share on other sites

Hallo,

 

ich bin ein objektive-c Neuling. Hier meine bisherigen Erfahrungen mit einem Poti:

 

 refToSelf = self;

liefert:

Implicit conversion of an Objective-C pointer to 'void *' is disallowed with ARC(Automatic Reference Counting)

 

Meine Versuche mit Hilfe von Google:

 

1. Selector:

  
- (void)callBackPoti:(id)sender:(int16_t)valuePoti{
  [_labelPoti setStringValue:[NSString stringWithFormat:@"Rotary Poti: %d",valuePoti]];
}

...

SEL sel = @selector(callBackPoti:);
rotary_poti_register_callback(&rotaryPoti, ROTARY_POTI_CALLBACK_POSITION, sel);

 

crashed beim Drehen am Poti

 

2. c Style Callback

void callBack(int16_t valuePoti)
{ 
  [[[[NSThread currentThread] threadDictionary] objectForKey:@"labelPoti"] setStringValue:[NSString stringWithFormat:@"Rotary Poti: %d", valuePoti]];  
}

...

rotary_poti_register_callback(&rotaryPoti, ROTARY_POTI_CALLBACK_POSITION, &callBack);

tut nix :-(

 

Vielleicht gibt es einen Mac Experten, der weiterhilft. Sonst bleibe ich beim NSTimer.

 

Gruß an alle Mac User

 

Link to comment
Share on other sites

Hi Manni,

 

die refToSelf Variante funktioniert bei mir, Dir fehlt bestimmt nur eine Zuweisung...bei mir siehts so aus.

 

1. Definition der Zeiger und der Callback-Methode (den Typecast (id) nicht vergessen) in der .m Datei (AppDelegate.m)

Dann bist Du die "Implicit conversion" Meldung los...

 

#import "AppDelegate.h"

 

void * refToLinearPotiSlider;

void * refToLinearPotiText;

 

void cb_lp_position(uint16_t position) {

    //NSLog(@" %@", @"callback from linearpoti...");

    [(id)refToLinearPotiSlider setIntegerValue: position];

    [(id)refToLinearPotiText setIntegerValue: position];

}

 

@implementation AppDelegate

 

2. Die Zeiger auf die GUI Elemente in dieser Methode zuweisen (AppDelegate.m). Ich setze einen Slider und ein Textfeld (IBOutlets).

 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification

{

    // Insert code here to initialize your application

    refToLinearPotiSlider = linearpoti_slider;

    refToLinearPotiText = linearpoti_text;

}

 

3. Registrierung der CallBack Methode in Deinem Code

 

    linear_poti_register_callback(&lp, LINEAR_POTI_CALLBACK_POSITION, cb_lp_position);

 

das ruft die CallBack Methode wenn ich mien Poti bewege und setzt dann den Wert im GUI (Slider & Textfeld).

 

Gruss kutte

Link to comment
Share on other sites

Ich stimmt da kutte zu, du solltest auf jeden Fall IBOutlets verwenden. Dazu wechselt du einfach in den Assistenzmodus (glaube der hieß so) und ziehst dein Control in das .h file deiner klasse.

Dabei wählst du dann Outlet aus und gibst ihm einen Namen. Anschließend überprüfen, ob im .m File ein @synthesize auf dein Outlet steht.

Wenn dem so ist, kannst du jetzt in diesem File direkt über das Outlet auf dein Control zugreifen.

Ich hoffe, dass ich keinen Mist erzähle, da ich mich nur mit der iOs Programmierung mit obj-c auseinandergesetzt habe, aber ich denke, dass es diesbezüglich identisch ist.

 

@obj-c

Die Sprache selbst ist einfach nur ein Graus. Das fängt mit der Syntax an und hört mit den "speziellen" Eigenschaften auf. Man kann sich letztlich auch nie sicher sein, dass eine Funktion auch wirklich aufgerufen wird (Message basiertes invoken von Methoden). Ist aber leider die einzige (vernünftige) Möglichkeit Apps zu programmieren.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...