Different C++ include statements throws errors in the Objective-C header - objective-c

I'm trying to use OpenCV in Objective-C++ code which I will call from Swift. First I used this answer for connecting Objective-C and Swift. So after these manipulations I get three files:
Bridging-Header.h:
#import "opencvtest.h"
opencvtest.h:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#include <opencv2/core/core.hpp>
//#include <dlib/image_loader/load_image.h>
#interface CustomObject : NSObject
- (cv::Mat)cvMatFromUIImage:(UIImage *)image;
#end
opencvtest.mm:
#import "opencvtest.h"
Error:
/Users/user/Documents/XcodeProjects/Swift_HelloWorld/Swift_HelloWorld/Swift_HelloWorld-Bridging-Header.h:5:9: note: in file included from /Users/user/Documents/XcodeProjects/Swift_HelloWorld/Swift_HelloWorld/Swift_HelloWorld-Bridging-Header.h:5:
#import "opencvtest.h"
^ /Users/user/Documents/XcodeProjects/Swift_HelloWorld/Swift_HelloWorld/opencvtest.h:23:4: error: expected a type
- (cv::Mat)cvMatFromUIImage:(UIImage *)image; ^ <unknown>:0: error: failed to import bridging header '/Users/user/Documents/XcodeProjects/Swift_HelloWorld/Swift_HelloWorld/Swift_HelloWorld-Bridging-Header.h'
Also, if I add line #include <dlib/image_loader/load_image.h> in the opencvtest.h then I get:
/usr/local/include/DLIB/string/string.h:7:10: error: 'sstream' file not found
#include <sstream>
^
<unknown>:0: error: failed to import bridging header '/Users/user/Documents/XcodeProjects/Swift_HelloWorld/Swift_HelloWorld/Swift_HelloWorld-Bridging-Header.h'
I want to note that all these errors occurs only when I put these include statements in this header, when I used it in .mm file all works fine. But I need them in the header for declarations.
So, how can I fix it?

The interface of your Objective-C objects usable in Swift and thus visible in the bridging header cannot reference any C++ types. You need to write an Objective-C++ wrapper in such a way that C++ types are only mentioned in your .mm files and in headers used in the .mm files. You can hide the parts of the interface that use C++ by using extensions in Objective-C++ code. Please see the following question and questions referenced there for examples of how to do that:
objective C opencv wrapper for swift project does not see STL headers

Related

Importing a Swift class of a framework in Objective-C (test) code

I'm trying to import a Swift class from my framework MyFramework in my unit test code:
In my Objective-C test file, I do:
#import MyFramework;
This line causes a compilation error:
Include of non-modular header inside framework module 'MyFramework': 'src/core-ios/MyFramework/Classes/MyFramework-Bridging-Header.h'
inside the "MyFramework-Swift.h" file. In that file, I can see a plain import from
#import "src/core-ios/MyFramework/Classes/MyFramework-Bridging-Header.h"
I'm not sure what to do. My framework "defines" modular headers, but it sound like the problem is that bridging header file which is included with its entire path rather than just doing #import <MyFramework/MyFramework-Bridging-Header.h>.
Any help appreciated!
While calling swift class in objective c
In Bridging-Header add #import "myClass.h". This is objective c class
where you are using swift class.
In myClass.m add #import < yourProjectName_swift.h >
In myClass.h or myClass.m add "#swiftcalss;"
first or second point may cause to your error.

Swift framework: Swift generated header doesn't contain modules I need

I've created a Swift framework and when I build it I get a generated header file called MyApp-Swift. In the header, all the methods are available for Objective-C users to implement. However, the header can't recognize NSString in the method's parameter. For example
- (void)getFirstName:(NSString *)lastName;
This method raises the error
Unknown type name NSString
I've checked some frameworks on GitHub and they seem to get around this by having the #import Foundation in the _has_feature(modules) section of the generated header file. However, I only have #import ObjectiveC in this section.
#if __has_feature(modules)
#import ObjectiveC;
#endif
How can I get this section of my header file to include the Foundation module so I won't get an error? Any help is appreciated.

Xcode and ZXingWidget: Importing Obj-C header files within .mm files

I use XCode 4.0 for developing an iOS project.
In my current project, I added the ZXingWidget library correctly but I had to change the .m extension in .mm in the class which implements MyViewController in order to import "QRCodeReader.h" and "ZXingWidgetController.h", the two headers I need to use the ZXing library.
Now, if in the same MyViewController.mm I want to also import my AppDelegate (which is obviously an Objective-C class), I receive a compile error which Xcode signals into other header files that are recursively added by my AppDelegate. These errors are of these kinds:
GCC 4.2 Error - Instance variable '<unnamed'> has unknown size
Expected ';' before 'public'
Expected unqualified-id before 'public'
I believe this is because I don't manage correctly the Objective-C and C++ mixing, and as I comment the line #import "MyAppDelegate.h" the error disappears.
Is there something I can do to fix this problem? Also a workaround could do!
Thanks!
Edit 1: The error does occur only if I import the App Delegate header in that .mm file. In every other .m file of my project I can successfully import the same App Delegate without errors. I feel there's something wrong with the .mm extension and GCC.
SOLVED: I had another external library interface which used this code
#interface Name : NSObject {
#private
#public
id var1;
int var2; // ecc...
}
And the error was pointing to the keyword #public. I commented the #private keyword and everything went just fine! I would be happy if someone could explain me the reason of this.

How to use c++ template class in objective C

I want to use a Template class of C++ in my Objective C project.
I have read that it is supported.
When I try to import the template class that is written in C++ I get lot of errors like
Cannot find protocol declaration for 'class'
etc..
Can anyone give me a simple example of this.
Waiting for reply.
You are putting the objective c++ code in a .mm file? You need to use .mm files to tell the compiler its allows to parse c++ constructs in addition to objective-c and c.
You can't just change the name of a header file from .h to .mm - the name of the file containing the #include / #import directive needs to change.
// file: main.m
#import "cppclassdef.h" //will not work
#import "cppclassdef.mm" // also will not work. additionally will confuse XCode which will try to compile the .mm file by itself.
// file: main.mm
#import "cppclassdef.h" // this is how to do it.

What is the difference between #import and #include in Objective-C?

What are the differences between #import and #include in Objective-C and are there times where you should use one over the other? Is one deprecated?
I was reading the following tutorial: http://www.otierney.net/objective-c.html#preamble and its paragraph about #import and #include seems to contradict itself or at least is unclear.
There seems to be a lot of confusion regarding the preprocessor.
What the compiler does when it sees a #include that it replaces that line with the contents of the included files, no questions asked.
So if you have a file a.h with this contents:
typedef int my_number;
and a file b.c with this content:
#include "a.h"
#include "a.h"
the file b.c will be translated by the preprocessor before compilation to
typedef int my_number;
typedef int my_number;
which will result in a compiler error, since the type my_number is defined twice. Even though the definition is the same this is not allowed by the C language.
Since a header often is used in more than one place include guards usually are used in C. This looks like this:
#ifndef _a_h_included_
#define _a_h_included_
typedef int my_number;
#endif
The file b.c still would have the whole contents of the header in it twice after being preprocessed. But the second instance would be ignored since the macro _a_h_included_ would already have been defined.
This works really well, but has two drawbacks. First of all the include guards have to be written, and the macro name has to be different in every header. And secondly the compiler has still to look for the header file and read it as often as it is included.
Objective-C has the #import preprocessor instruction (it also can be used for C and C++ code with some compilers and options). This does almost the same as #include, but it also notes internally which file has already been included. The #import line is only replaced by the contents of the named file for the first time it is encountered. Every time after that it is just ignored.
The #import directive was added to Objective-C as an improved version of #include. Whether or not it's improved, however, is still a matter of debate. #import ensures that a file is only ever included once so that you never have a problem with recursive includes. However, most decent header files protect themselves against this anyway, so it's not really that much of a benefit.
Basically, it's up to you to decide which you want to use. I tend to #import headers for Objective-C things (like class definitions and such) and #include standard C stuff that I need. For example, one of my source files might look like this:
#import <Foundation/Foundation.h>
#include <asl.h>
#include <mach/mach.h>
I agree with Jason.
I got caught out doing this:
#import <sys/time.h> // to use gettimeofday() function
#import <time.h> // to use time() function
For GNU gcc, it kept complaining that time() function was
not defined.
So then I changed #import to #include and all went ok.
Reason:
You #import <sys/time.h>:
<sys/time.h> includes only a part of <time.h> by using #defines
You #import <time.h>:
No go. Even though only part of <time.h> was already included, as
far as #import is concerned, that file is now already completely included.
Bottom line:
C/C++ headers traditionally includes parts of other include files.
So for C/C++ headers, use #include.
For objc/objc++ headers, use #import.
#include works just like the C #include.
#import keeps track of which headers have already been included and is ignored if a header is imported more than once in a compilation unit. This makes it unnecessary to use header guards.
The bottom line is just use #import in Objective-C and don't worry if your headers wind up importing something more than once.
I know this thread is old... but in "modern times".. there is a far superior "include strategy" via clang's #import modules - that is oft-overlooked..
Modules improve access to the API of software libraries by replacing the textual preprocessor inclusion model with a more robust, more efficient semantic model. From the user’s perspective, the code looks only slightly different, because one uses an import declaration rather than a #include preprocessor directive:
#import Darwin; // Like including all of /usr/include. #see /usr/include/module.map
or
#import Foundation; // Like #import <Foundation/Foundation.h>
#import ObjectiveC; // Like #import <objc/runtime.h>
However, this module import behaves quite differently from the corresponding #include: when the compiler sees the module import above, it loads a binary representation of the module and makes its API available to the application directly. Preprocessor definitions that precede the import declaration have no impact on the API provided... because the module itself was compiled as a separate, standalone module. Additionally, any linker flags required to use the module will automatically be provided when the module is imported. This semantic import model addresses many of the problems of the preprocessor inclusion model.
To enable modules, pass the command-line flag -fmodules aka CLANG_ENABLE_MODULES in Xcode- at compile time. As mentioned above.. this strategy obviates ANY and ALL LDFLAGS. As in, you can REMOVE any "OTHER_LDFLAGS" settings, as well as any "Linking" phases..
I find compile / launch times to "feel" much snappier (or possibly, there's just less of a lag while "linking"?).. and also, provides a great opportunity to purge the now extraneous Project-Prefix.pch file, and corresponding build settings, GCC_INCREASE_PRECOMPILED_HEADER_SHARING, GCC_PRECOMPILE_PREFIX_HEADER, and GCC_PREFIX_HEADER, etc.
Also, while not well-documented… You can create module.maps for your own frameworks and include them in the same convenient fashion. You can take a look at my ObjC-Clang-Modules github repo for some examples of how to implement such miracles.
If you are familiar with C++ and macros, then
#import "Class.h"
is similar to
{
#pragma once
#include "class.h"
}
which means that your Class will be loaded only once when your app runs.
IF you #include a file two times in .h files than compiler will give error.
But if you #import a file more than once compiler will ignore it.
#include it used to get "things" from another file to the one the #include is used in.
Ex:
in file: main.cpp
#include "otherfile.h"
// some stuff here using otherfile.h objects,
// functions or classes declared inside
Header guard is used on the top of each header file (*.h) to prevent including the same file more then once (if it happens you will get compile errors).
in file: otherfile.h
#ifndef OTHERFILE
#define OTHERFILE
// declare functions, classes or objects here
#endif
even if you put #include "otherfile.h" n time in your code, this inside it will not be redeclared.
In may case I had a global variable in one of my .h files that was causing the problem, and I solved it by adding extern in front of it.
#include vs #import preprocessor directives
History:
#include -> #import -> [Precompiled Headers .pch] -> [#import Module(ObjC);] -> [import Module(Swift)]
#import is a next generation of #include which solves double inclusion and recursive includes for current .h file. Just single copy of included .h body in the current file
#import == #include + guard
guard looks like
#ifndef <some_unique_name>
#define <some_unique_name>
<header_body>
#endif
#include guardWiki(macro guard, header guard, file guard) - prevents multi including a header by a preprocessor that can slow down a build time
#include and #import uses a kind of copy/paste mechanism - recursively copy .h file body(everything except #include, #import directives. It means that the result file will not contain #include, #import directives)
You can check result if select .m file Product -> Perform Action -> Preprocess ".m"
#include example
//A.h
#interface A : NSObject
- (int)startA;
#end
//ViewController.h
#include "A.h"
ViewController.m after preprocessing
#interface A : NSObject
- (int)startA;
#end
#interface ViewController : UIViewController
#end
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
}
#end
double inclusion example
//A.h
#interface A : NSObject //Build time error: Duplicate interface definition for class 'A'
#end
//B.h
#include "A.h"
//C.h
#include "A.h"
//#import "A.h" to solve
#include "B.h"
recursive includes example
//A.h
#include "B.h" //Build time error: #include nested too deeply
//#import "B.h" to fix it
#interface B : NSObject //Build time error: Duplicate interface definition for class 'A'
#end
//B.h
#include "A.h" //Build time error: #include nested too deeply
//#import "A.h" to fix it
#interface B : NSObject //Build time error: Duplicate interface definition for class 'B'
#end
[#import in .h or .m]