How to run a simple objective-c in linux - objective-c

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;
}

Related

OpenCV K-Nearest Implementation with Objective-C++ throws EXC_BAD_ACCESS

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?

Newbie Objective C Error such as _main

I've been tinkering all day, and I can't seem to fix this error.
Here's the code:
//
// main.m
// Learning ObjC
//
// Created by Nickirv on 8/9/15.
// Copyright (c) 2015 Nickirv. All rights reserved.
//
#import <Foundation/Foundation.h>
#interface Person: NSObject{
int age;
int weight;
}
-(void) print;
-(void) setAge: (int) a;
-(void) SetWeight: (int) w;
#end
And it outputs this issue:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I would appreciate any help! Thank you very much!
You can't delete the main boilerplate code:
int main(int argc, const char * argv[]) {
#autoreleasepool {
}
return 0;
}
In the end Objective-C is "C" and the program starts execution by calling main. Additionally Objective-C code needs to execute in an autoreleasepool.
You define class #interfaces and #implemtations outside of (generally above) the boilerplate but the first line of code to run must be within the autoreleasepool scope {}.
Here is an example Objective-C program similar to what the OP seems to want using #properties for simplicity and demonstration.
It is important to study Objective-C documentation until the following code is fully understood, td;dr does not work for this.
#import <Foundation/Foundation.h>
#interface Person: NSObject
#property int age;
#property int weight;
- (void)print;
#end
#implementation Person : NSObject
- (void)print {
printf("Age: %i, weight: %i", self.age, self.weight);
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
Person *don = [[Person alloc] init];
don.weight = 130;
don.age = 23;
[don print];
}
return 0;
}
Output:
Age: 23, weight: 130

GCC Undefined Reference to xxx

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?

GNU runtime: class_createInstance return makes pointer from integer without a cast

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>

Compiling objective-c programs without gnustep on ubuntu

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!