Objective-C unter Linux

Hallo community,

nach dem ich meine C-Kenntnisse aufgefrischt habe, wollte ich eine langes Vorhaben mal endlich angehen: Objective-C unter Linux und komme zur ersten Frage: Wenn ich aus meinen 2 Testdateien zuerst die Objekt-Dateien erstelle mit:

cc -c Ellipse.m Geo.m

kommen verschiedene Warnmeldungen, wie so was:

Geo.m: In Funktion »main«:
Geo.m:7:4: Warnung: »Ellipse« antwortet möglicherweise nicht auf »+alloc« [standardmäßig aktiviert]
Geo.m:7:4: Warnung: (Nachrichten ohne passende Methodensignatur [standardmäßig aktiviert]
Geo.m:7:4: Warnung: werden als »id« zurückgebend angenommen und akzeptieren [standardmäßig aktiviert]
Geo.m:7:4: Warnung: »...« als Argumente.) [standardmäßig aktiviert]
Geo.m:11:4: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »printf« [standardmäßig aktiviert]

linke ich dann diese zu einer Ausführbaren Datei mit:

cc -o Geo Geo.o Circle.o Ellipse.o -lobjc

Wird ohne weitere Ausgaben die Datei „GEO“ erstellt, bei einem ausführen, eben jener, kommt:

Speicherzugriffsfehler (Speicherabzug geschrieben)

Was jemand woran das liegt?

Zur 2. Frage: Jetzt wollte ich das GNUstep mit einbinden (Warum wird das eigentlich nicht so richtig fortgeführt, die Entwicklung damit unter Linux erinnert stark an Windows95-Buttons, zwar gibt es Ansätze, wie Etoile, welches sich schon sehen lassen kann,aber erst in V0.4 vorliegt.Finde die Idee richtig gut (App-Bundle, Interface-Builder usw. -> Ein Programm, spielend portierbar auf MAC, Windows, Linux und umgekehrt, Java ist einfach von der Performance her für wirklich grosse Projekte zu lahm, mit Objective-C sieht das aber anderes aus) …ok ich schweife aus, zurück zu meiner Frage, ich hab eine kleine Testapplikation (mit gorm) geschrieben und wollte GTK2 einbinden mit:

gcc `pkg-config –cflags –libs gtk+-2.0` -lgnustep-base -fconstant-string-class=NSConstantString -o “./myprogram” $(find . -name ‘\*.m’) -I /usr/include/GNUstep/ -L /usr/lib/GNUstep/ -std=c99 -O3

jedoch kommt diese Fehlermeldung:

/usr/include/gnustep/: file not recognized: Is a directory
collect2: Fehler: ld gab 1 als Ende-Status zurück

Klar, es ist ein Directory und soll alle Unterverzeichnisse und Include-Dateien darin mit einbinden, wie bekomme ich das hin???

Noch zur Info: Meine Entwicklungsumgebung ist Fedora mit xfce4 (wer die post im Linux-Thread mitbekommen hat, habe das als 2. System neben Debian installiert(Xubuntu weg) und bin abgesehen von dem Mousepad, welches nicht funktioniert wie sollte, sehr begeistert (lvm und Verschlüsselung im Installer waren super einfach + da ich ein 2. Monitor 24" (kann auf dem kleinen Laptop-Ding nicht arbeiten und meine Lieblingstastatur angeschlossen habe) stellte Fedora alles perfekt ein,was ich bis heute in der Art nicht unter Ubuntu noch unter Debian so hinbekommen habe (perfekte Monitor Aufteilung), Hut ab …ok ich schweife schon wieder ab.

Zurück zum Thema, wer kann mir bei den oben genannten Problemen helfen??

Gruß XXD

P.S. An wer-weiss-was, vielleicht sollte man Objective-C mal mit aufnehmen (ist immerhin Platz 3 aller benutzer Sprachen), hab es jetzt hier ins C-Forum geschrieben, da ja die Fragen schon recht „C“-spezifisch sind.

Howdy,

Geo.m: In Funktion »main«:
Geo.m:7:4: Warnung: »Ellipse« antwortet möglicherweise nicht
auf »+alloc« [standardmäßig aktiviert]
Geo.m:7:4: Warnung: (Nachrichten ohne passende
Methodensignatur [standardmäßig aktiviert]
Geo.m:7:4: Warnung: werden als »id« zurückgebend angenommen
und akzeptieren [standardmäßig aktiviert]
Geo.m:7:4: Warnung: »…« als Argumente.) [standardmäßig
aktiviert]
Geo.m:11:4: Warnung: Unverträgliche implizite Deklaration der
eingebauten Funktion »printf« [standardmäßig aktiviert]

linke ich dann diese zu einer Ausführbaren Datei mit:

cc -o Geo Geo.o Circle.o Ellipse.o -lobjc

leider habe ich meine grosse Kugel gerade nicht dabei… Mal im Ernst, laesst sich das Geo.m soweit runterbrechen, dass die Fehlermeldungen noch da sind und hier einstellen? In C/C++ wuerde ich sagen stdio.h nicht included …

Wird ohne weitere Ausgaben die Datei „GEO“ erstellt, bei einem
ausführen, eben jener, kommt:

klar, denn du hast die Warnings ja auch vorher schon bekommen.

Speicherzugriffsfehler (Speicherabzug geschrieben)

Was jemand woran das liegt?

Na, z.B. Zugriff ueber nicht initialisierte Pointer in deinem Programm oder in den benutzten Libs. Ohne Source ==> Glaskugel

gcc pkg-config –cflags –libs gtk+-2.0 -lgnustep-base
-fconstant-string-class=NSConstantString -o “./myprogram”
$(find . -name ‘*.m’) -I /usr/include/GNUstep/ -L
/usr/lib/GNUstep/ -std=c99 -O3

jedoch kommt diese Fehlermeldung:

/usr/include/gnustep/: file not recognized: Is a directory
collect2: Fehler: ld gab 1 als Ende-Status zurück

Also zum einen sollte das -I und -L vielleicht vor dem eigentlichen Sourcefiles stehen und zum anderen vertraegt der eine oder andere Compiler keine Spaces zwischen -I bzw -L und dem Pfad.

Gruss
norsemanna

Hallo norsemanna,

leider habe ich meine grosse Kugel gerade nicht dabei… Mal
im Ernst, laesst sich das Geo.m soweit runterbrechen, dass die
Fehlermeldungen noch da sind und hier einstellen? In C/C++
wuerde ich sagen stdio.h nicht included …

Anbei der Code für Geo.m:

#import "Ellipse.h"

int main(int argc, char \*\*argv)
{
 Ellipse \*ellipse;

 ellipse = [[Ellipse alloc] init];
 [ellipse setR1: 3.3];
 [ellipse setR2: 1.5];
 [ellipse printDim];
 printf("Fläche: %fn", [ellipse area]);
}

und Ellipse.h:

#import 

@interface Ellipse: Object
{
 float r1,r2;
}
+ (id) init;
- (void) setR1: (float)r;
- (void) setR2: (float)r;
- (void) setAchse1: (float)a Achse2: (float)b;
- (void) printDim;
- (float) area;
- (float) r1;
- (float) r2;
@end
  • Ellipse.m:

    #import
    #import
    #import „Ellipse.h“

    @implementation Ellipse

    • (id) init
      {
      return [super init];
      }
    • (void) setR1: (float) r
      {
      r1 = r;
      }
    • (void) setR2: (float) r
      {
      r2 = r;
      }
    • (void) setAchse1: (float)a Achse2: (float)b;
      {
      r1 = a;
      r2 = b;
      }
    • (void) printDim
      {
      printf(„Ellipse (%f, %f)n“, r1, r2);
      }
    • (float) area
      {
      return r1 * r2 * 3.16;
      }
      @end

Ich bin der Sache schon etwas näher gekommen, wenn ich alles in eine Datei schreibe mit folgenden Code:

#import 

@interface Test : Object
{
 int x; 
}
 
-(int) getX;
-(void) setX:frowning:int) xs;
 
@end

@implementation Test
- (int) getX {
 return x;
}
-(void) setX:frowning:int) xs {
 x = xs; 
} 
@end

int main( int argc , char \*\*argv )
{
 Test \*test = [Test new];
 [test setX:5];
 int r = [test getX];
 printf("%d\n",r);

}

und folgendermaßen kompiliere:

gcc -x objective-c -Wno-import Geo.m -lobjc

läuft es. Der Fehler ist definitiv bei [alloc] init. Hier die gdb Ausgabe (./Geo), Breakpoint bei 3 gesetzt:

Breakpoint 1, main (argc=2, argv=0xbffff1d4) at Geo.m:7
7 ellipse = [[Ellipse alloc] init];
Missing separate debuginfos, use: debuginfo-install glibc-2.15-56.fc17.i686 libgcc-4.7.0-5.fc17.i686 libobjc-4.7.0-5.fc17.i686

und noch die print-Ausgabe der Variable „ellipse“:

(gdb) print ellipse
$1 = (struct Ellipse \*) 0x43f7dff4

Alle libs: glibc-2.15-56.fc17.i686 libgcc-4.7.0-5.fc17.i686 libobjc-4.7.0-5.fc17.i686 sind auf dem Rechner vorhanden.

gcc pkg-config –cflags –libs gtk+-2.0 -lgnustep-base
-fconstant-string-class=NSConstantString -o “./myprogram”
$(find . -name ‘*.m’) -I /usr/include/GNUstep/ -L
/usr/lib/GNUstep/ -std=c99 -O3

jedoch kommt diese Fehlermeldung:

/usr/include/gnustep/: file not recognized: Is a directory
collect2: Fehler: ld gab 1 als Ende-Status zurück

zum anderen vertraegt der
eine oder andere Compiler keine Spaces zwischen -I bzw -L und
dem Pfad.

Probiert -> gleiche Fehlermeldung.

Gruß XXD

Ok, ich mache es noch komplizierter, die libs waren installiert, aber nicht die debuginfos dazu, hab das jetzt nachgeholt und bekomme eine „bessere“ Debugausgabe:

Breakpoint 1, main (argc=2, argv=0xbffff1d4) at Geo.m:7
7 ellipse = [[Ellipse alloc] init];
(gdb) next

Program received signal SIGSEGV, Segmentation fault.
\_\_objc\_responds\_to (sel=, object=0x8049e00)
 at /usr/src/debug/gcc-4.7.0-20120507/libobjc/sendmsg.c:398
398 res = sarray\_get\_safe (dtable, (size\_t) sel-\>sel\_id);
(gdb) list
393 
394 objc\_mutex\_unlock (\_\_objc\_runtime\_mutex);
395 }
396 
397 /\* Get the method from the dispatch table. \*/
398 res = sarray\_get\_safe (dtable, (size\_t) sel-\>sel\_id);
399 return (res != 0) ? YES : NO;
400 }
401 
402 BOOL

Nun gut, ab jetzt versteh ich eigentlich gar nichts mehr …aber habe was gefunden, ist glaube ich, ein Redhat-Bug in gcc, welchre von der Beschreibung genau auf das Dilemma zutrifft. Bloß weiss ich nicht viel damit anzufangen, vielleicht lässt sich ja hier jemand finden der mir Erklären kann, wie und was ich patchen muss. Hier der Link Gruß XXD

Also mal abgesehen von der nicht vorhandenen Implementierung fuer r1/r2 (die letzten Zeilen in Ellipse.h) und dem fehlenden return in main, laesst sich das bei mir sehr gut mit

gcc -Wall Ellipse.m Geo.m -lobjc

uebersetzen und ohne Fehlermeldungen.
Auch das Resultat laeuft bei mir praechtig.

$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

Kannst du deinen Compiler auf 4.6.3 upgraden?

Gruss
norsemanna

Moin,

hab es gerade unter Debian getestet gcc - Version 4.4.5 und läuft einwandfrei.

Kannst du deinen Compiler auf 4.6.3 upgraden?

Da ich grad in Debian bin, weiss ich nicht die exakte gcc - Version, glaube aber zu wissen es war die 4.6.0, werde sie heute Abend mal upgraden und hoffentlich geht es dann, ansonsten mach ich unter Debian weiter.

Danke für die Unterstützung. Gruß XXD

Nur zur Info - Problem 2 ist auch gelöst
Probiert:

gcc `pkg-config –cflags –libs gtk+-2.0` -lgnustep-base -fconstant-string-class=NSConstantString -o “./myprogram” **$(find . -name ‘\*.m’)** -I /usr/include/GNUstep/ -L /usr/lib/GNUstep/ -std=c99 -O3

Das fett gedruckte verursachte den Fehler, gibt man jedoch die Dateien einzeln an geht es.

Gruß XXD