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

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

Related

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.

OSX command line app linker error

I have created an OSX command app in Xcode 5
Here is the main.m
#import <Foundation/Foundation.h>
#import "ConnectionListener.h"
#import "SOMatrix.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSLog(#"Hello, World!");
print_m();
}
return 0;
}
and here is my header file:
#ifndef __GDC1__SOMatrix__
#define __GDC1__SOMatrix__
#ifdef __cplus
#include <iostream>
#endif
int print_m();
#endif /* defined(__GDC1__SOMatrix__) */
And here is a partial listing of the SOMatrix.mm file
#include "SOMatrix.h"
#include <iostream>
using namespace std;
int print_m() {
// logic removed to keep it short; no compile time error
return 0;
}
When I build the project I got a linker error:
Undefined symbols for architecture x86_64:
"_print_m", 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)
I don't understand why the function is showhow changed to have a leading underscore in the name ('_print_m').
Why this error occurs? Do I need to add the .mm file explicitly to the project?
You need to change these lines:
#ifdef __cplus
#include <iostream>
#endif
to this in your .h file:
#ifdef __cplusplus
#include <iostream>
extern "C"
{
#endif
with a companion:
#ifdef __cplusplus
}
#endif
at the end of the .h file.
Because you are trying to access a C++ function from Objective-C, and C++ tends to do a bit of name mangling (adding the underscore, for example). Adding the "extern "C"" bit allows your Objective-C code to find your C function declarations. The answers to this related question might elaborate on things a bit better than I can.

Calling Functions using Objective-C and 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

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.

Using static .lib (c) in iOS Project - Expected '=',',',';','asm' or 'attribute' before

I am trying to use static libraries that are written in c in an iOS Project. I included the .lib files and the .h into the iOS project. When I try to import the header files in one of my objective-C classes I get a lot of Expected '=',',',';','asm' or 'attribute' before... errors in the .h file of my static library.
I am using xCode4 for Development which seems to have added the libs correctly. When I open the project with Xcode 3 the libs are added to the Target Group "link binary with libraries" as stated in How to resolve linking error - static lib iPhone.
I got the static libs from a company that actually uses these libraries so I guess the header file is not at fault. I could not find any errors myself.
Is there a way to use .lib files with correct header files in an ios project? Or do I have to do anything besides adding the lib files to the target group in order to use them in my project?
Best Regards,
Mike
edit
the actual error message:
Expected * before *
Expected '=',',',';','asm' or 'attribute' before _far _pascal
The actual code where the header is imported:
#import <Foundation/Foundation.h>
#import "SomethingDll.h"
#interface AccountingEntry : NSObject {
NSString *entryDescription;
NSDate *entryDate;
double entryAmount;
NSString *entryType;
}
#property (nonatomic, retain) NSString *entryDescription;
#property (nonatomic, retain) NSDate *entryDate;
#property (nonatomic) double entryAmount;
#property (nonatomic, retain) NSString *entryType;
//class methods go here
//instance methods go here
-(id)initWithDescription:(NSString *)eDesc date:(NSDate*)eDate amount:(double)eAmount type:(NSString *)eType;
#end
The .h file of the lib.
#ifndef __SOMETHING_DLL
#define __SOMETHING_DLL
// constants for a function
#define FIRST_ERRTEXT 0
#define NEXT_ERRTEXT 1
/*
...
some other #define of constants
*/
// Callback-Pointer Definitionen
#define INFO_FUNC_DECL BOOL (CALLBACK *lpInfoFunc)(int)
#define FILETRANS_FUNC_DECL void (CALLBACK *lpFileTransFunc)(int,long)
// Funktionsdeklarationen
#ifdef WIN32
#define IMPORTAPI WINAPI
#else
#define IMPORTAPI _far _pascal
#endif
#ifdef __cplusplus
extern "C" {
#endif
void IMPORTAPI Something_Config( int iLogLevel, char *szLogFile,
long lTimeOut_Connect, long lTimeOut,
long lTimeout_GetFile, long lTime_Info,
int iSSLVersion, char *szSSLCipher,
char *szVerifyCertificateFile, char *szVerifyCertificatePath);
/*
...
a lot of other functions
...
*/
#ifdef __cplusplus
}
#endif
#endif // End
It seams that this lib is for Win32, the _far _pascal directive is not available on gcc and the other errors may come from missing definitions.
Maybe you have to look for another lib to do the job.