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.
Related
I want to make an app in Swift that simply record via the mic of the iPhone and then play the sound recorded.
For that, I'd like to use the lib Superpowered that is a static library with header files.
For that, I tried to drag and drop the .a and headers files in my project (Xcode create for me a bridging header file), add the .a in "Linked Frameworks and Libraries" in Xcode > Target > General (and so in Xcode > Target > Build phases > "Link Binary With Libraries" too) and index the .h files path in Xcode > Target > Build Settings > Search Paths > Library Search Paths.
But with that I have the error "ld: symbol(s) not found for architecture arm64"
Exactly the same as here XCode: Undefined symbols for architecture arm64 error and I tried all the solutions that I found on the web for that, still no way to compile.
SO !
Superpowered gives us a sample app to show how to mix Objective-C++ and use their lib within a Swift project (Here's a link to the git if you want https://github.com/superpoweredSDK/Low-Latency-Android-Audio-iOS-Audio-Engine).
Here is some screenshots of the sample project with what I understand and what I don't :
The Bridging-Header-File with the prototypes of the methods of the lib that I want to use within my Swift code (I don't like this but if it's the only way...).
The viewController file where the code in Swift is, and where I can create a Superpowered object thank's to the Bridging-Header-File, and call the methods that I've put in it.
And wtf I don't even understand why this Objective-C++ file is here and what it contains. It comes out from nowhere, not even their lib files.
So with this sample project in mind, I've created my own project, here is some screenshots :
The same Bridging-Header-File that in the sample project except that I include SuperpoweredIOSAudioIO.h so I can use SuperpoweredIOSAudioIODelegate.
My viewController file where the code in Swift is, and where I can create a Superpowered object thank's to the Bridging-Header-File, and call the methods that I've put in it.
Until here, it's great, except that I can't for exemple create a SuperpoweredRecorder object. If I try to include the SuperpoweredRecorder.h file in my Bridging-Header-File I have these errors :
So I saw that it is because SuperpoweredRecorder.h includes some .cpp files and I have to create a wrapper for cpp (a little bit like I did with the bridging header, no ?) but that includes a .h and a .mm file and I don't know what I have to put in that .mm file (the code of SuperpoweredRecorder.cpp ? But I don't have access to it)
So yes, I'm a little bit confused with all that stuff, can you help me to understand how can I use all the Superpowered lib in my Swift project please ?
As I said in comment to #OmniProg, I had a little conversation with the CTO of Superpowered that helped me a lot to find the solution below.
So, as Swift cannot interact directly with C++ but can with Objective-C, I had to create objects in Objective-C++ (.mm file, a mix between C++ and Objective-C) that wrap C++ classes of the lib Superpowered.
Here is an example with the SuperpoweredRecorder object from the lib :
Here I create a .h file where I prototype my wrapper with the name SuperpoweredRecorderWrapped, and I also prototype in it all the methods of the SuperpoweredRecorder of the lib that I want to use.
Then I create a new .m file that I rename .mm and I implement SuperpoweredRecorderWrapped on it.
I import both SuperpoweredRecorderWrapped.h and SuperpoweredRecorder.h.
I create a SuperpoweredRecorder object as property named _wrapped and in my methods, I call the corresponding method of the _wrapped object.
With that, when I'll call start of a SuperpoweredRecorderWrapped in my Swift code, this one will call start of _wrapped, a SuperpoweredRecorder object. See the trick ?
And finally I include all the wrapped classes in my Bridging-Header, like that I can instantiate my wrapped objects from Swift.
NOTE: All the C++ code HAVE to be in .mm files, that's why I make my #include of .h that contains C++ code in my .mm file and not in my .h file.
I haven't programmed in Objective-C++, but I do have experience with C, C++, Objective-C, and Swift, so here are some observations and ideas based on looking at the Superpowered SDK and sample code.
A bridging header lets Swift interface directly with Objective-C, and since Objective-C is a strict superset of C, this implies interfacing with C as well. However, you cannot interface directly with C++, and that's where Objective-C++ comes to the rescue. From what I'm seeing you can mix Objective-C and C++ code in Objective-C++, which allows Objective-C to use C++ classes.
Now on to some specifics.
The bridging header in the SuperpoweredFrequencies example that you looked at introduces a new Objective-C class, Superpowered, which is not part of the library, but of the example, and is implemented in Superpowered.mm. It is an Objective-C++ file, because Superpowered calls some C++ code.
Looking at Superpowered.mm, you will see that it imports Objective-C headers:
#import "SuperpoweredFrequencies-Bridging-Header.h"
#import "SuperpoweredIOSAudioIO.h"
as well as C and C++ headers:
#include "SuperpoweredBandpassFilterbank.h"
#include "SuperpoweredSimple.h"
We could have used import instead of include for C++ code, too, but they are probably using include just to emphasize that it is C++ code. Looking at SuperpoweredBandpassFilterbank.h, we see that SuperpoweredBandpassFilterbank is a C++ class. It is used in Superpowered.mm by the Superpowered Objective-C++ class, see the filters member, which is a pointer to a SuperpoweredBandpassFilterbank object.
In the project you attempted to build, I see where the Superpowered interface is declared in the bridging header, but I don't see an implementation. The failure to #import SuperpoweredRecorder.h is due to SuperpoweredRecorder.h being a C++ header. The #include should be in your Objective-C++ (.mm) file, it's useless in the bridging header, since Swift can't make sense of C++ anyhow.
Hopefully this is helpful. Welcome to the world of C++.
I'm a bit surprised that you would have to provide prototypes of method.
I used Objective C libraries in my Swift project before and I only had to add the header files in my bridging header.
See example from my project. The bridging header contains just that:
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "QTouchposeApplication.h"
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <VungleSDK/VungleSDK.h>
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
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.
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
I'm trying to include some C++ code into my iPhone project and I'm getting the following compiler error:
"error:expected initializer before '<' token"
at this code construct:
template<typename T, P_UINT_32 BEG, bool OQ, bool OVR, bool DBG>
P_UINT_32 EKType<T, BEG, OQ, OVR, DBG>::getSizeX() const {
return n;
}
It looks like the XCode compiler is not recognizing this as a valid C++ syntax. I have named my C++ files with .h and .mm, and I've set the types of the files to sourcecode.cpp.h and sourcecode.cpp.cpp
Anyone has an idea as to why I'm getting this error?
You probably have the header being included by a .M file somewhere. It's amazing how these things can get pulled in, so make sure all of your .M files are renamed .MM.
You only need to name a file .mm if the file contains both Objective-C and C++.
If the file only contains C++, it should have the extension .cpp
If the file is a mix of ObjC and C++, then it should have the extension .mm and have its type set as sourcecode.cpp.objcpp
Are you sure that the source file you are trying to compile includes the declaration of the EKType class (or struct) and the declaration P_UINT_32?
I would think you'd get a similar error if the compiler wasn't aware of EKType or P_UINT_32.