I'm making a simple test to see if I can run Objective-C on Linux without GNUStep, so I followed an example here on SO to get it running, here's my code:
//WSObject.h
#include <objc/runtime.h>
#include <stdio.h>
#interface WSObject
+ (id) alloc;
- (void) dealloc;
- (void) hello;
#end
//WSObject.m
#include "WSObject.h"
#implementation WSObject
+ (id) alloc {
return class_createInstance(self, 0);
}
+ (void) dealloc {
object_dispose(self);
}
+ (void) hello {
puts("Hello, world");
}
#end
//test.m
#include "WSObject.h"
int main(int argc, const char *argv[]) {
WSObject *obj = [WSObject alloc];
[obj hello];
[obj dealloc];
return 0;
}
When I then try to compile it with gcc test.m -o test -lobjc
I get the following error:
/tmp/ccDzvsol.o:(.data+0x80): undefined reference to `__objc_class_name_WSObject'
collect2: error: ld returned 1 exit status
Any help?
Related
I have an issue when implementing OpenCV's K-Nearest to Objective-C++
Below is my sample code for implementation:
BridgeClass.h
#ifndef BridgeClass_h
#define BridgeClass_h
#include <Foundation/Foundation.h>
#interface BridgeClass : NSObject
- (void)testFunction;
#end
#endif
BridgeClass.mm
using namespace ml;
typedef KNearest KNN;
#implementation BridgeClass{
KNN* kNearest;
}
- (id) init {
self = [super init];
if (self) {
kNearest = KNN::create();
}
return self;
}
- (void) testFunction {
BOOL test = kNearest->isTrained();
NSLog(#"Test: %d", test);
}
But when I called testFunction, it shows error:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x400000048)
What is the problem with my implementation?
I just started learning "accessor methods" on Objective C and I get stuck. I couldn't find why I am getting that "Duplicate Symbol Error" that stops the program from running. Should be a easy thing! but I will appreciate some help.
The xCode issue navigator complains:
Ld /Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Products/Debug/Shapes-Object normal x86_64
cd "/Users/leo/Google Drive/Documentos/Formación/Curso iOS/Pre iOS, pilares/Learn Objective C on the Mac/Ejercicios/Chapter 06/SPLIT 04.02 Shapes-Green-Circles MAS FACIL"
export MACOSX_DEPLOYMENT_TARGET=10.7
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk - L/Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Products/Debug -F/Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Products/Debug -filelist /Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Intermediates/Shapes-Object.build/Debug/Shapes-Object.build/Objects-normal/x86_64/Shapes-Object.LinkFileList -mmacosx-version-min=10.7 -fobjc-link-runtime -framework Foundation -Xlinker -dependency_info -Xlinker /Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Intermediates/Shapes-Object.build/Debug/Shapes-Object.build/Objects-normal/x86_64/Shapes-Object_dependency_info.dat -o /Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Products/Debug/Shapes-Object
duplicate symbol _colorPrint in:
/Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Intermediates/Shapes-Object.build/Debug/Shapes-Object.build/Objects-normal/x86_64/main.o
/Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Intermediates/Shapes-Object.build/Debug/Shapes-Object.build/Objects-normal/x86_64/Circulo.o
duplicate symbol _colorPrint in:
/Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Intermediates/Shapes-Object.build/Debug/Shapes-Object.build/Objects-normal/x86_64/main.o
/Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Intermediates/Shapes-Object.build/Debug/Shapes-Object.build/Objects-normal/x86_64/SALCHICHA.o
duplicate symbol _colorPrint in:
/Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Intermediates/Shapes-Object.build/Debug/Shapes-Object.build/Objects-normal/x86_64/main.o
/Users/leo/Library/Developer/Xcode/DerivedData/Shapes-Object-ctkpgnxalegjsdbbylyuaqxtisrd/Build/Intermediates/Shapes-Object.build/Debug/Shapes-Object.build/Objects-normal/x86_64/Shape.o
ld: 3 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
That is my main():
#import <Foundation/Foundation.h>
#import "Circulo.h"
#import "SALCHICHA.h"
void FuncionDibujarFormas (id Formas[], int count)
{
for (int i = 0; i < count; i++) {
id shape = Formas[i];
[shape Dibujar];
}
} // FuncionDibujarFormas
// --------------------------------------------------
// The main function. Make the shapes and draw them
int main (int argc, const char * argv[])
{
id Formas[3];
Formas[0] = [Circulo new];
[Formas[0] definirColor: kRojo];
Formas[2] = [SALCHICHA new];
[Formas[2] definirColor: kVerde];
FuncionDibujarFormas (Formas, 3);
return (0);
} // main
That is the "superclass" header for Shape.h:
#import <Foundation/Foundation.h>
typedef enum {
kRojo,
kVerde,
} Color;
//--------------------------------------------------
NSString *colorPrint (Color switchColor) //"Color" se asigna "switchColor"
{
switch (switchColor) {
case kRojo:
return #"rojo";
break;
case kVerde:
return #"verde";
break;
}
return #"malign#";
} // colorPrint
#interface Shape : NSObject
{
Color RellenarColor;
}
- (void) definirColor: (Color) RellenarColor;
- (void) Dibujar;
#end // Shape
That's the Shape.m:
#import "Shape.h"
#implementation Shape
- (void) definirColor: (Color) ImplementationRellenarColor
{
RellenarColor = ImplementationRellenarColor;
} // definirColor
- (void) Dibujar
{
} // draw
#end // Shape
That's the "childclass" Circulo.h:
#import "Shape.h"
#interface Circulo : Shape
#end // Circulo
Thats the child class Circulo.m :
#import "Circulo.h"
#implementation Circulo
- (void) definirColor: (Color) ImplementationRellenarColor
{
if ( ImplementationRellenarColor == kRojo ) {
ImplementationRellenarColor = kVerde;
}
[super definirColor: ImplementationRellenarColor];
} // definirColor
- (void) dibujar
{
NSLog (#"dibujando un circulo %#", colorPrint(RellenarColor));
} // dibujar
#end // Circulo
That's "chilclass" SALCHICHA.h:
#import "Shape.h"
#interface SALCHICHA : Shape
#end // SALCHICHA
Thats chilclass SALCHICHA.m
#import "SALCHICHA.h"
#implementation SALCHICHA
- (void) dibujar
{
NSLog (#"dibujando una SALCHICHA %#", colorPrint(RellenarColor));
} // dibujar
#end // SALCHICHA
You have a C function implementation in a header file (Shape.h):
NSString *colorPrint (Color switchColor) //"Color" se asigna "switchColor"
Each time you import the header you duplicate the symbol.
So using in pure Objc you should have someting like:
In header:
+(NSString*)colorPrint:(Color)switchColor;
In implementation:
+(NSString*)colorPrint:(Color)switchColor {
switch (switchColor) {
case kRojo:
return #"rojo";
case kVerde:
return #"verde";
}
return #"malign#";
}
And to call it:
NSLog (#"dibujando un circulo %#", [Shape colorPrint:RellenarColor]);
Edit: Fixed parameter name
I am trying to make a new Objective-C root class on the GNU runtime. Here is what I have so far:
foo.h:
#include <objc/objc.h>
#interface Foo {
Class isa;
int bar;
}
+ (id) alloc;
+ (id) newWithBar: (int) bar;
- (id) initWithBar: (int) bar;
- (void) p;
- (void) dispose;
#end
foo.m:
#import <foo.h>
#include <stdio.h>
#implementation Foo
+ (id) alloc {
return class_createInstance(self, 0);
}
+ (id) newWithBar: (int) bar {
return [[self alloc] initWithBar: bar];
}
- (id) initWithBar: (int) bar_ {
bar = bar_;
}
- (void) p {
printf ("bar=%d\n", self->bar);
}
- (void) dispose {
object_dispose(self);
}
#end
and a little test program, main.m:
#import <foo.h>
int main(int argc, char *argv[]) {
Foo *foo = [Foo newWithBar: 3];
[foo p];
[foo dispose];
return 0;
}
When I compile foo.m, I get the following warning:
foo.m: In function ‘+[Foo alloc]’:
foo.m:7:3: warning: return makes pointer from integer without a cast [enabled by default]
Why? When I dive into the header files, I can see that class_createInstance returns id. What am I doing wrong here?
You need to include the header for the objective C runtime. The default behaviour of the compiler is to assume undeclared functions return an int.
#include <objc-auto.h>
Sorry - answer above is for OS X/iOS. For GNU you need to include runtime.h as well as objc.h
#include <objc/runtime.h>
EDITED
I have been trying to start coding in Objective-c. Its just a simple program to try getter and setter methods. Also print Hello World. THe following is my code:
#import <objc/Object.h>
#interface Car:Object{
int wheel: 5;
}
- (int)wheel;
- (void)setWheel: (int)newWheel;
#end
#include <stdio.h>
#implementation Car
- (int)wheel{
return wheel;
}
- (void)setWheel: (int)newWheel{
wheel = newWheel;
}
#end
#include <stdlib.h>
int main(void){
printf("Hello World");
}
I now get garbage
/tmp/cc3UC6jY.o: In function `__objc_gnu_init':
hello.m:(.text+0x6d): undefined reference to `__objc_exec_class'
/tmp/cc3UC6jY.o:(.data+0x1c0): undefined reference to `__objc_class_name_Object'
collect2: error: ld returned 1 exit status
I used the the command gcc -o hello hello.m -lobjc
I have spent hours googling this answer.
The following variation of your code compiled and ran for me:
#import <objc/Object.h>
#interface Car : Object {
int wheel;
}
- (int)wheel;
- (void)setWheel: (int)newWheel;
#end
#implementation Car
- init {
wheel = 5;
return self;
}
- (int)wheel {
return wheel;
}
- (void)setWheel: (int) newWheel {
wheel = newWheel;
}
#end
#include <stdio.h>
int main(void){
printf("Hello World\n");
id myCar = [[Car alloc] init];
printf("Wheel value is %d\n", [myCar wheel]);
return 0;
}
is there any way to compile objective c programs on ubuntu without the use of GNUStep? I want to use the default C standard libraries and all but with Objective-C's OOB syntax. The problem I am having now is once I have all the methods up, I need a way to call them. In Mac I would just alloc and init it but on Linux when I try to compile this, clang just gives me an error.
#include <stdio.h> // C standard IO library (for printf)
#include <stdlib.h> // C standard library
// Interface
#interface test
-(void)sayHello :(char *)message;
#end
// Implementation
#implementation test
-(void)sayHello :(char *)message {
printf("%s", message);
}
int main(int argc, char *argv[]) {
test *test = [[test alloc] init];
[test sayHello:"Hello world"];
}
You can compile objective-c with gcc, but remember to use the -lobjc switch so the compiler knows what language you're using.
You'll also need to include the following header:
#import <objc/Object.h>
...and extend Object from your interface. See the hello world example for objective-c here:
http://en.m.wikipedia.org/wiki/List_of_Hello_world_program_examples#O
Good question - it got me to dig into the matters myself, since I want to rewrite several old Python projects in a normal language (C/ObjC), so I aim both to stay away from Crap++ and avoid GNUstep overhead. Here goes my try-and-test solution:
Foo.h:
#import <objc/Object.h>
#interface Foo: Object
{
#private
int
bar;
}
+ (id) alloc;
+ (id) new;
- (id) init;
- (id) set_bar: (int)value;
- (int) get_bar;
#end
Foo.m:
#import <stdio.h>
#import <objc/runtime.h>
#import "Foo.h"
#implementation Foo
+ (id) alloc
{
puts(__func__);
return class_createInstance(self, 0);
}
+ (id) new
{
return [[self alloc] init];
}
- (id) init
{
puts(__func__);
bar = 31;
return self;
}
- (id) set_bar: (int)value
{
puts(__func__);
bar = value;
return self;
}
- (int) get_bar
{
puts(__func__);
return bar;
}
#end
main.m:
#import <stdio.h>
#import "Foo.h"
int
main
()
{
id
foo = [Foo new];
printf("old bar: %i\n", [foo get_bar]);
[foo set_bar: 10];
printf("new bar: %i\n", [foo get_bar]);
return 0;
}
Makefile:
run: main.o Foo.o
gcc $^ -o $# -lobjc
main.o: main.m Foo.h
gcc -c $< -o $#
Foo.o: Foo.m Foo.h
gcc -c $< -o $#
The output I've got:
+[Foo alloc]
-[Foo init]
-[Foo get_bar]
old bar: 31
-[Foo set:bar:]
-[Foo get_bar]
new bar: 10
Looks like it works!