Calling Functions using Objective-C and C++ - objective-c

Alright, I'm trying to call a function in xcode but apparently it isn't working. I made an objective-c class, and typed in the following code into the implementation file:
#import "Person.h"
#implementation Person
void printthis()
{
NSLog(#"Hi, I have been printed");
}
int main(int argc, const char * argv[])
{
#autoreleasepool {
printthis();
}
return 0;
}
#end
Apparently, it returns the following error in xcode:
ld: 1 duplicate symbol for architecture x86_64
clang: error:
linker command failed with exit code 1 (use -v to see invocation)

Did you already have a main function somewhere else (probably main.m ?). If so the linker got confused -- you are not supposed to have duplicates of main function

Related

Why calling objc function from objc++ could result in build failure?

Given this MVP code:
objc_funcs.h
#import <Foundation/Foundation.h>
NSString* doFoo(void);
objc_funcs.m
#import <Foundation/Foundation.h>
NSString* doFoo()
{
return #"fffuuu";
}
main.mm
#import "objc_funcs.h"
int main(int argc, char * argv[]) {
doFoo();
return 0;
}
If I leave it this way, the build will result in
Undefined symbols for architecture x86_64:
"doFoo()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Though if I rename main.mm -> main.m, the build will go just fine.
WAIDW? đŸ˜–
The problem relates to C vs C++ linkage.
The normal way this is handled in C headers is testing for the __cplusplus preprocessor macro and inserting an extern "C" if needed. CoreFoundation provides the CF_EXTERN_C_BEGIN and CF_EXTERN_C_END macros that handle this:
#if !defined(CF_EXTERN_C_BEGIN)
#if defined(__cplusplus)
#define CF_EXTERN_C_BEGIN extern "C" {
#define CF_EXTERN_C_END }
#else
#define CF_EXTERN_C_BEGIN
#define CF_EXTERN_C_END
#endif
#endif
Using these your objc_funcs.h becomes:
#import <Foundation/Foundation.h>
CF_EXTERN_C_BEGIN
NSString* doFoo(void);
CF_EXTERN_C_END
if you don't want to use them you could use
#import <Foundation/Foundation.h>
#ifdef __cplusplus
extern "C"
#endif
NSString* doFoo(void);
You have to make it valid for C++ compiler by either converting objc_funcs to .mm file or wrapping the import in main.mm with extern "C" {}:
extern "C" {
#import "objc_funcs.h"
}
You could read more about it here

Programming with GLFW and Glew on Mac OS X

I have the following code:
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import </usr/local/Cellar/glew/1.12.0/include/GL/glew.h>
#import </usr/local/Cellar/glfw2/2.7.9/include/GL/glfw.h>
int main(int argc, const char * argv[])
{
#autoreleasepool
{
if(!glfwInit())
{
exit(EXIT_FAILURE);
}
}
return 0;
}
I get the following errors when compiling: glew.h User-defined Issue Gltypes.h included before glew.h Modules Issue Declaration of PFNGLCOPYTEXSUBIMAGE3DPROC must be imported from module 'OpenGL.GL3' before it is required
There are another 19 errors that are all semantic errors. Does anyone know how to fix this?
As it turned out I didn't properly compile the library files.

Why clang doesn't find .h file in #include "" in the same directory?

This is my first question on this site, so please be patient with me. I tried searching for an answer but couldn't find any relevant.
I have main.m, Person.h and Person.h files in a current directory. In main.m I include Person.h. Then I try to compile main.m, but it gives an error that Person object was not found.
Here is main.m:
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
// Create an instance of Person
Person *person = [[Person alloc] init];
[person setWeightInKilos:96];
[person setHeightInMeters:1.8];
float bmi = [person bodyMassIndex];
NSLog(#"person has a BMI of %f", bmi);
}
return 0;
}
Person.h:
#import <Foundation/Foundation.h>
#interface Person : NSObject
{
// 2 instance variables
float heightInMeters;
int weightInKilos;
}
// instance methods
- (void)setHeightInMeters:(float)h;
- (void)setWeightInKilos:(float)w;
- (float)bodyMassIndex;
#end
Person.m:
#import <Foundation/Foundation.h>
#implementation Person
- (void)setHeightInMeters:(float)h
{
heightInMeters = h;
}
- (void)setWeightInKilos:(float)w
{
weightInKilos = w;
}
- (float)bodyMassIndex
{
return weightInKilos / (heightInMeters * heightInMeters);
}
#end
Here is the error I get as I try to compile using 'cc main.m -framework Foundation':
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_Person", referenced from:
objc-class-ref in main-24c686.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I even tried adding the current directory in PATH, but it didn't help.
Thanks in advance for help.
That error is not about the include file "Person.h". The problem is that the Person
class it not found by the linker.
The reason is that you did not add the "Person.m" file to your command line:
cc main.m Person.m -framework Foundation

error: ‘NSString’ undeclared (first use in this function)

I am getting this error when i try to compile Object-c program in cygwin Windows 7, but this program executed in Xcode.
main.m:5:3: error: ‘NSString’ undeclared (first use in this function)
#include <stdio.h>
int main (int argc, const char * argv[])
{
NSString *str1 = #"1st string";
NSString *str2 = #"2nd string";
NSLog(#"Hello, World!");
return 0;
}
Executed using the following CMD in cygwin,
gcc -c -Wno-import main.m
can you one help me how solve this compilation error.
Windows doesn't come with a Foundation library, so NSString isn't available by default. You should try GNUstep or you could cross-compile from Xcode on a Mac using Cocotron. Whichever you choose, look at its documentation to find out how to use it (at a minimum you'll need to #import <Foundation/Foundation.h> and link the Foundation library).
Make sure that you are have the following code at the top of your .h or .m file:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
You can also put the code in your Prefix.pch file.

objective c gnustep - cannot separate interface and implementation files

I am using gnustep for objective-c on windows. If i keep interface and implementation files of a class together with main file, it compiles without error and gives expected output.
Following is the example:
// File "classA.h"
#import <Foundation/Foundation.h>
#interface classA: NSObject
{
int a;
}
-(void) print;
#end
// File "classA.m"
#import "classA.h"
#implementation classA
-(void) print
{
a = 10;
NSLog(#"a = %i", a);
}
#end
// File "test.m"
#import "classA.h"
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(#"start");
classA *objA = [[classA alloc] init];
[objA print];
[objA release];
NSLog(#"done");
[pool drain];
return 0;
}
However, if i put the interface and implementation files separately, on compiling using following command
gcc `gnustep-config --objc-flags` -o program program.m -L /GNUstep/System/Library/Libraries -lobjc -lgnustep-base
i get following error
undefined reference to `__objc_class_name_myNewClass'
collect2: ld returned 1 exit status
How do i keep the files separate and still compile the program successfully
Thanks for help
Regards
You have a linker error here. Most likely, you are not including a required header file for myNewClass.
I know this is old, but double check the name of compiled files just in case the error is in a different file.
Reasons:
The class myNewClass is not referenced in the code above and there are no other imports other than Foundation.
The name of the file in the code comments and the file you appear to be compiling differ.
// File "test.m"
gcc `gnustep-config --objc-flags` -o program program.m
By the look of it, the given code should compile when split out.
Also, about the question "Also how do i included "Compiled files"?", assuming you mean a .o file, you just need to include the header file (.h) and make sure the compiler can find the matching .o file. Related: How do I link object files in C? Fails with "Undefined symbols for architecture x86_64"