Mixing Objective C ,(*.m , *.mm & .c /.cpp ) files - c++

In my project Core libraries are part of C/C++ files, while UI needs to be developed in Objective C,
I am able to access/Call C++ functions from Objective C/.mm files
but reverse no luck so far, i.e. i am not able to call Objective C functions from C++ Files,
when i tried to include Objective C header even system header
#import <foundation/foundation.h>
getting around 1000+ compilation error,
something like this
/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:180:0 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:180: error: expected unqualified-id before '#' token
/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:182:0 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:182: error: expected initializer before '*' token
/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:183:0 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:183: error: 'NSString' was not declared in this scope
/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:183:0 /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:183: error: 'aSelectorName' was not declared in this scope
Am i missing some pre-compile flag etc..
can anyone suggest me, the best possible way to call/access objective C class which is inherited from NSObject, without modifying much C++ code, i just need to call one function
Code structure / Order to include header files are
Some system header file
Some Core Class Header file
#import <foundation/foundation.h>

If you have a .cpp file with C++ code that needs to use Objective-C as well, either rename that .cpp file to .mm or pass -x objective-c++ to the compiler.

I found it imposible to use any Objective-c in the C++ header files.
However, you can include Objective-c in the implementation files.
(.mm or you can set how to interpret .cpp files in the info of the file. Choose Info->General:FileType:Sourcecode.cpp.objcpp )
Use
cppClass.h:
class objcClass;
objcClass* mMemberVariable;
cppClass.mm:
#import "objcClass.h";
void cppFunction(){
[objcClass message];
}
in the cpp header file.
Then include the header that defines the class in the .cpp or .mm file.

If you use Qt, there is Q_FORWARD_DECLARE_OBJC_CLASS macro which can be used to forward declare an Objective-C class.
As a reference, here is the implementation:
#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
# ifdef __OBJC__
# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) #class classname
# else
# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
# endif
#endif

I used a technique of the name expand files depending on a programming language. Also, I added "-x objective-c ++" to the compiler, but the problem remained. I was helped by council for the link, pay attention to the "file type" parameter.

In XCode 11, it can be done by changing the build setting Compile Source as (GCC_INPUT_FILETYPE) to Objective-C++ (sourcecode.cpp.objcpp). By doing this, there is no need to change the file extension type to mm.

Related

Swift Compiler Error 'iostream' not found

I've tried to implement a project which I've found on github.
https://github.com/hossamghareeb/Facebook-POP-Tutorial
While I was implementing the .h and .m files I've got an error which was saying XCode could not find my 'iostream' file.
I'm working in SWIFT, using bridging-headers to use the framework. When I try to build the original project it works, but mine always fails.
How can I add my iostream file?
Thanks in advance!
Swift bridging does not support Objective C++ files. This means that any headers that consume or expose C++ entites (like std::vector; std::iostream) cannot be added to the bridging header.
The POP bridging header contains:
#import "POP.h"
You should really only #import that file in your own bridging header, rather than trying to #import all the .h files.
If you need to consume some of the API that's defined in .mm files that isn't exposed with an Objective C or plain C header, then you'll have to make your own header file that exposes it (and probably a back-end that implements what you've exposed).
The reason why you can use .mm files in a library that's being used by Swift is because all swift uses is the interface to those files - i.e. the .h files, and as long as those files are in plain C or Objective C, then you can make use of the code that is implemented in the .mm file. The .mm files are compiled by Objective C++ compiler (clang++)

How to #import C++ Header File in iPhone/iPad Objective C Project

Referred Question: Problem when #import C++ Header File in iPhone/iPad Project
Well, my project is relatively huge and cannot solve that either changing ALL or PART OF my project files .m to .mm or changing the ALL or PART OF file types in File Inspector.
That is because both my colleagues and library authors DOES NOT follow the C++ standard strictly, such as assigning void* to int* and other various violations. Objective C would allow these and just gives warnings.
The C++ header file I want to #import is a library. It uses keyword namespace in its header, while its implementation is in an .a assembly file. That means it is nearly impossible to hack them. Besides that, my project also includes other libraries that are compatible only with Objective C.
Does anyone know how to solve this?
The ways I could imagine is as follows:
Find an alternative for namespace, but still I want to write
codes like QCAR::Renderer in my project.
Tell the compiler to recognized C++ header(Well, that might not be
possible)
EDIT
#ifdef __cplusplus
# include MyCPPHeader.h
#endif
If I use that, would MyCPPHeader.h really get included in an Objective-C environment? I guess not. And that's against the principles of not hacking libraries.
EDIT
Even I changed these .mm files to include that C++ Header, i would get an link error saying Undefined symbols for architecture armv7:. This happens when my .mm files including .h headers in other libraries.
I have solved this a year ago, but for other people who are looking for an answer, here is the solution.
Say the C++ style header is named cpp.h. In my project, I never #import "cpp.h". I wrote a C style header, named c.h, as a wrapper header for cpp.h. Then I wrote a C++ implementation source file, named c.mm to implement the function define in c.h by calling functions in cpp.h. If I want to call functions in cpp.h, I #import c.h and use the wrapper function instead.
Below is the explanation in a possibly clearer way:
cpp.h C++ style header file using the namespace, its implementation is in assembly code so it is hard to change
c.h C style header as the wrapper for cpp.h
c.mm C++ implementation implements functions in c.h by calling functions in cpp.h
#import "c.h" to use the wrapper functions

Unknown type name 'class'; did you mean 'Class'?

I'm trying to implement AQRecorder.h class from SpeakHere Apple Xcode project example, but even I rename my implementation class to ext. *.mm and put line with #import "AQRecorder.h" still getting error "Unknown type name 'class'; did you mean 'Class'?" and many others.
Which according to me means that it is not recognized as C++ class.
Any help will be appreciated.
I've just had this exact problem. I had a view controller using the AQRecorder class from AQRecorder.mm.
When I included AQRecorder.h in my view controller these errors occurred. It appeared to me because my straight objective-c view controller (named as a .m file) was including C++ header files the compiler was throwing spurious errors.
There are two solutions. The quickest is to rename the view controller class including AQRecorder.h to be a .mm file, in my case UIRecorderViewController from .m to .mm.
Or, move the following includes:
#include "CAStreamBasicDescription.h"
#include "CAXException.h"
Out of AQRecorder.h into AQRecorder.mm. This means that straight C++ style header files will no longer be included (by reference) in your plain Obj-C source.
Hope that helps, and makes sense.
In my case, this error was caused by cyclical "Import" statements in two classes: the header file for each class included the header of the other class, resulting in the Unknown type name 'ClassA'; did you mean 'ClassB'? error:
This is how my import statements were configured when I got this error. In ClassA.h:
Import "ClassB.h"
In ClassB.h:
Import "ClassA.h"
To fix it, I used the #class forward declaration directive to forward-declare ClassA in ClassB.h (this promises the pre-compiler that ClassA is a valid class, and that it will be available at compile time). For example:
In ClassA.h:
Import "ClassB.h"
In ClassB.h:
#class ClassA;
This fixed the Unknown type name 'ClassA' error, but also introduced a new error: ClassB.m: Receiver type 'ClassA' for instance message is a forward declaration. For example:
To fix this new error, I had to import ClassA.h at the top of the implementation file of ClassB (ClassB.m). Both errors are now resolved, and I get zero errors and warnings.
For example, I now have:
In ClassA.h:
Import "ClassB.h"
In ClassB.h:
#class ClassA;
In ClassB.m:
Import "ClassA.h"
Both error messages are now resolved.
i met the same error with you, hope my solution may help you. The Xcode compiler could compile objective-c & c++ in the "*.mm" file, so you may change all your filename which import "AQRecorder.h"(all direct & indirect) file with ".mm" postfix. But you may not do that, you may find that the relationship between SpeakHereController and SpeakHereViewController is some tricky, i just learned how he used it, that create the SpeakHereController object in a nib file, so SpeakHereViewController file is not have to import the "AQRecorder.h" file. my English is stupid, i hope my answer may help you.
IMPORTANT: Select "Compile Source As" variable in compiler settings and set its value to "Objective-C++".
It looks like this problem is impossible to resolve.
If it is possible to shift #include "myC++.h" into *.mm file then it works.
But if You need to use it from your objectiveC.h file it fails.
I guess this is bug from apple. There is a way to specify *.mm instead of *.m
but there is nothing similar to *.hh instead of *.h
I fixed this problem today.If you #include or #import a C++ *.h file or C++/OC mixed *.h file in YourHeader.h,you MUST have a YourHeader.mm . If not,then all your C++ file and C++/OC mixed file will show compile errors.
Using XCode, it's possible to use the "language" Objective C++, which allows you to mix Objective C and C++.
My solution maybe looks ridiculus, but in xcode 4.2,
To add Apple Audio examples codes, I moved all files individually, and it is worked as a charm!
I mean not dragging whole folder, drag one by one all individual file in a spesific folder.
I resolved this issue the following:
Originally, the files were placed inside the project, but not inside the the correct file structure.
YES, I am aware it is not an actual structre as it is only for visual issues, BUT when i moved the Header and the CPP file inside the PROJ folder all worked.
This problem can be solved by changing the following build settings:
Under Apple LLVM Compiler 4.2 - Language
C++ Language Dialect (Gnu++11 works for me)
C++ Standard Library (Libc++ works for me)
It is also necessary to name the .m files as .mm, if you are letting Xcode use file extension to decide how to compile each file.
From my own experience, following things should be taken care.
Select "Compile Source As" variable in compiler settings and set its value to "Objective-C++" i.e Build Settings->Apple LLVM 5.1 - Language->Compile Source As->Objective-C++ (in Xcode 5.1.1)
Change the relevant files which include a C++ header file from .m to .mm (sometimes you need to change all .m to .mm). This was answered by #Diziet above.
If you face incompatible type errors, explicitly do type casting of the required type. These errors might not have shown up when it was .m file.
Specifically, if you're compiling a NDK C/C++ code, and got:
Unknown type name 'jclass'; did you mean 'class'?
It is very likely that the file containing 'jclass' is #include-ed in .c/.cpp files (directly or indirectly) which are to be built into a library. And the solution is: remove that #include.
This is one of the common mistakes done : Circular dependencies.
Consider an example :
File : B.h
#import "A.h"
File : A.h
#import "C.h"
File : C.h
#import "B.h"
This introduces Circular dependency.
Just redeclare in C.h as :
#class B;

C++ and Objective-C

I need to use C++ file in my project, it's called CAXException.hpp, and row in project targets "Compile Sources As" - "According to file type" not Objective-C++. But when it's compiling it always displays me error error: expected '=', ',', ';', 'asm' or '__attribute__' before 'CAXException'
in code:
class CAXException //<-------error here
{}
Please help me to fix it..
If I understand you correctly, you have a C++ header file (.hpp) that you want to include from Objective-C file. Unfortunately, you can't do that directly. You'll have to use a workaround.
The easiest is to change the compilation option of each and every Objective-C file (.m) that include this C++ header file (either directly or indirectly) to be compiled as an Objective-C++ file. This can be done either by renaming the files to .mm extension or by changing the option for the compiler for the file.
If this work for you, this will be the easiest, however Objective-C++ is not a complete superset of Objective-C (as C++ is not a superset of C), and some valid Objective-C is invalid Objective-C++ (if C++ keywords are used as variables names).
If this happens, you'll have to create an Objective-C wrapper to the class, with an implementation in Objective-C++ that simply delegate to the C++ class. That is create an CAXExceptionWrapper.h Objective-C file, containing something like:
#interface CAXExceptionWrapper {
#private
void* _CAXExceptionImpl;
}
- (id)init;
// ...
#end
And an `CAXExceptionWrapper.mm' Objective-C++ file containing:
#import "CAXException.hpp"
#implementation CAXExceptionWrapper
- (id)init {
if ((self = [super init])) {
_CAXException = new CAXExceptionWrapper;
}
return self;
}
// ...
#end
And then in your Objective-C files, include the wrapper Objective-C header instead of the C++ header.
class CAXException //<-------error here
{};
^^^
you are missing the ;
And Your compiler seems not to recognize the C++ keyword class, which is strange. Most likely, you are missing some ; before this class definition or some other syntax error but before this.
It is possible that that header is being included from an objective-c (.m extension) source code file. The source code file that includes that header must be an objective c++ one, i.e. ends with .mm or you can force objective c++ by explicitly changing the "Compile sources as..." setting.

Problem when #import C++ Header File in iPhone/iPad Project

I have a C++ class I would like to use in an iPhone/iPad project.
I created this file in different ways (like with "New File" => C++) and the error is always the same.
When I compile the project without having any #import (of the .h C++ class), it's ok.
But as soon as I #import the header file in one of my header objective-c file, I get error like :
error: vector: No such file or directory
or
error: expected '=', ',', ';', 'asm' or 'attribute' before ':' token"
I tried setting different values to the file type (of C++ class) in File Info, renaming my objc class in .mm etc, but it doesn't seem to work.
So I must have missed something about importing the .h c++ class in the objc header file, but what :p ^^
SOLUTION thanks to Vlad
1°) To include the header c++ file :
#ifdef __cplusplus
#include "Triangulate.h"
#endif
2°) Renaming the objc file in .mm AND in his File Info (right clic) setting file type as sourcecode.cpp.objcpp
Thanks for helping !
Vincent
Note: Xcode requires that file names
have a “.mm” extension for the
Objective-C++ extensions to be enabled
by the compiler.
Trying to use C++ in Objective-C code residing in a file with .m extension is the most probable cause of the problem because compiler just does not recognize C++ constructs according to the error message. Renaming your .m file to .mm should help.
For more details, see Using C++ with Objective-C.
Assuming you want to use an Objective-C class in an Objective-C++ source file, there's no problem at all. The only restriction is that your .h file must be Objective-C clean. This means that you can't use any C++-isms in it, or that if you do you must wrap them all in #ifdef __cplusplus. The header will be compiled in ObjC mode when it's #included by a plain Objective-C file, so it has to eliminate any C++isms for that situation (1). So your Objective-C header file should include C++ header like this:
#ifdef __cplusplus
# include MyCPPHeader.h
#endif