Include bei Mix von C++ und Objective-C

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Include bei Mix von C++ und Objective-C

    Hallo zusammen,

    ich habe hier ein kleineres Problem mit einer Klasse, die als Objective-C++ implementiert wurde. Ich möchte diese Klasse gerne in einem reinen Objective-C Objekt verwenden.
    Ich kann aber leider nicht einfach das passende Header File inkludieren, denn das enthält leider eine Menge C++ Nonsens, was dann zu Compiler-Fehler führt.
    Also möchte ich das irgendwie abstrahieren, aber ich finde da nicht die richtige Strategie. Und ich brauche auch nicht die gesamte Klasse, sondern eigentlich möchte ich nur 2, 3 ausgewählte Methoden aufrufen.

    Was habe ich bisher versucht:
    • ich habe die Methoden, die ich nutzen möchte, als Protocol definiert
    • ich habe die Header-Datei meines Protocols inkludiert, sowohl im Objective-C++, als auch im Objective-C Header
    • ich habe die Objective-C++ Klasse mittels @class bekannt gemacht (forward declaration) und in meiner Objective-C Interface Definition als Variable myObject definiert.
    • myObject wird mittels getter/setter übergeben, es wird nicht mittels alloc/init erzeugt
    Wenn ich jetzt aber die entsprechenden Methoden aufrufen möchte, z.B. mit [myObject Methode1]dann gibt es einen Compiler Fehler:
    Receiver type 'myObject' for instance message is a forward declaration

    Warum kann ich denn nicht einfach eine ObjC Message an ein Object schicken? Im schlimmsten Fall gibt des doch nur einen entsprechenden Log-Eintrag, oder?

    Und wenn ich das Objekt auf mein Protocol teste (z.B. mit if ([myObject conformsToProtocol: @protocol (PlayerInfo)]== YES), dann kommt da auch immer NO raus.
    Warum?

    Wie kann ich also ein Objective-C++ in einem reinen Objective-C Kontext nutzen?


    C-Quellcode: PlayerInfo.h

    1. @protocol PlayerInfo <NSObject>
    2. - (short*) audioDriverSampleBuffer;
    3. - (BOOL) audioDriverIsPlaying;
    4. - (unsigned int) currentNumberOfSamples;
    5. @end


    Quellcode

    1. #import <Cocoa/Cocoa.h>
    2. #import "PlayerInfoProtocol.h"
    3. @class SPPlayerWindow;
    4. @interface SPBigOscilloscopeView : NSView
    5. {
    6. SPPlayerWindow* myObject;
    7. }
    8. - (void)setPlayerWindow:(SPPlayerWindow*)newObject;
    9. @end
    Alles anzeigen
    --
    Wer ist dieser Root und warum gehören ihm alle meine Dateien??

    SIDplay5 for macOS on GitHub
  • Sorry, ich bin etwas denkfaul, aber man kann eine Klasse nicht in "ObjC++" implementieren. Man impl sie entweder in ObjC oder in C++, was man beides in einem ".mm"-File tun kann.
    Bitte beschreibe klarer, wie die fragliche C++-Klasse definiert ist, mit der du Probleme hast, also z.B. als Auszüge from Source-code.

    Meist läuft es darauf hinaus, daß du eine Wrapper-Klasse erzeugen musst. Das kommt schon daher, daß C++ eine explizite Speicherverwaltung von Objekten erfordert (man muss sie explizit mit "delete" freigeben), während bei ObjC das seit ARC praktisch automatisch passiert. So müßte der Wrapper, in ObjC geschrieben, dann im "init" die C++-Klasse anlegen und sich das Objekt in einer Property merken, und dann im "dealloc" wieder mit delete freigeben. Und jede Funktion der C++-Klasse musst du dann in der ObjC-Klasse nachbilden und weiterleiten.
    Apps: apps.tempel.org (Find Any File, iBored, iClip, Prefs Editor)
    Blog: http://blog.tempel.org
    Über mich: tempel.org/AboutThomasTempelmann

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von tempelmann ()

  • Sorry ich habe zwar keine Ahnung was Apple mit C und C++ gemacht hat, aber c++ ist ein Superset von C. das heisst du kannst C in C++ verwenden, aber es funktioniert nicht umgedreht...

    Das sollte Systemübergreifend der Fall sein!

    Daher, was Du dir wünschst, sollte nicht funktionieren, sollte deine C++ (Funktion, Klasse, Implementierung) nicht reine C konstrukte verwendet.
  • Sorry, komme jetzt erst wieder dazu, hier weiterzumachen.

    tempelmann schrieb:

    So müßte der Wrapper, in ObjC geschrieben, dann im "init" die C++-Klasse anlegen und sich das Objekt in einer Property merken, und dann im "dealloc" wieder mit delete freigeben. Und jede Funktion der C++-Klasse musst du dann in der ObjC-Klasse nachbilden und weiterleiten.
    Ich glaube, das ist genau mein Problem. Ich habe dieses Projekt ja irgendwann zu Intel/PPC Zeiten übernommen, und wollte schon immer ein Refactoring machen, komme aber leider zeitlich nie dazu. Und jetzt muss ich leider in diesem Mischmasch was ändern.

    Im aktuellen Fall habe folgende ObjC Implementation (gekürzt):

    C-Quellcode: SPBigOscilloscopeView.m

    1. #import <Cocoa/Cocoa.h>
    2. #import "PlayerLibSidplay.h"
    3. #import "SPExporter.h"
    4. #import "SPOscilloscopeWindowController.h"
    5. #import "PlayerInfoProtocol.h"
    6. // Forward declares
    7. class AudioDriver;
    8. @class SPStatusDisplayView;
    9. @class SPInfoWindowController;
    10. @class SPInfoContainerView;
    11. @class SPStilBrowserController;
    12. @class SPPreferencesWindowController;
    13. @class SPBrowserDataSource;
    14. @class SPSourceListDataSource;
    15. @class SPExportController;
    16. @class SPGradientBox;
    17. @class SPMiniPlayerWindow;
    18. @class SPVisualizerView;
    19. @class SPRemixKwedOrgController;
    20. extern NSString* SPTuneChangedNotification;
    21. extern NSString* SPPlayerInitializedNotification;
    22. extern NSString* SPUrlRequestUserAgentString;
    23. @interface SPPlayerWindow : NSWindow <NSSplitViewDelegate, PlayerInfo>
    24. {
    25. ...
    Alles anzeigen
    Also muss ich entweder SPPlayerWindow.h so umbauen, dass kein C++ verwendet wird (auch nicht über Includes), oder für jede C++ Klasse entsprechende Wrapper bauen.
    Schon mal Danke für den Schubs in die richtige Richtung!
    --
    Wer ist dieser Root und warum gehören ihm alle meine Dateien??

    SIDplay5 for macOS on GitHub
  • Neu

    Voriges Jahr hat Apple doch was in Swift eingbaut (siehe Xcode 15), um C++ mit Swift zu interfacen. Vielleicht kann man das verwenden, um passende Swift-Header für die C++-Klassen zu generieren, die du dann wiederum mit "@obj"-Attributen für ObjC zugänglich machen kannst.

    Google mal "swift c++ bridge"
    Apps: apps.tempel.org (Find Any File, iBored, iClip, Prefs Editor)
    Blog: http://blog.tempel.org
    Über mich: tempel.org/AboutThomasTempelmann