How to include OpenCV in Cocoa Application? - cocoa

when I create an xCode project with the 'Command Line Tool' c++ stdc++ template, i am able to include and compile opencv headers and run some code.
But i want to use OpenCV in a 'Cocoa Application' context. When created with that template, i got compile errors when I include the OpenCV headers in main.mm. (I already changed main.m to main.mm, the '//NSApplicationMain(argc, (const char **) argv);' is commented out)
One of those errors is: "Statement-expressions are allowed only inside functions"
I suppose its some kind of compiler version error, but when i compare the project build settings i cant find differences.
Do you have any ideas/expertise?

I ran into the same problem, I spent 2 days doing serious system tracing and as expected, the solution was so simple that an 8-year-old could have found it more quickly than I did.
Ready for this?
In the .mm file where you want to use OpenCV, you need to do your #include "opencv2/opencv.hpp" BEFORE any other includes. That's it! Just move it up a line and watch your problem magically disappear faster than that rug that really tied the room together.
This is for OpenCV 2.2 by the way, hence the new include file. Also if your XCode project uses a prefix header file (look in "Other Sources" for a "YourProjectName_Prefix.pch" file), then you'll need to put your #include "opencv2/opencv.hpp" there instead of in any other file.

Ian Charnas's Answer is correct, but there is one modification I would make.
This article has a more specific solution, and an explanation of why you need to do this.
http://aptogo.co.uk/2011/09/opencv-framework-for-ios/
// Add this new section BEFORE the #import statements for UIKit and Foundation
#ifdef __cplusplus
#import <opencv2/opencv.hpp>
#endif

Even if you rename your "main.m" to "main.mm" and moving the "#include opencv2/opencv.hpp" to the top (in the main file), the preprocessor will insert cocoa.h first because of the precompiled header files nemed something like "_Prefix.pch". To avoid such problems
- delete the #import statement or
- insert an #import statement above the cocoa.h import statement

Try adding: -lstdc++ to the "Other linker flags" in the build settings for your Cocoa app.
A cocoa application made by the Xcode templates won't link include the c++ library in it's settings by default.

add this to your .pch file
#ifdef __cplusplus
#import <opencv2/opencv.hpp>
#endif
dont forget to convert all of your .m files into .mm files

You'll probably find it easier to use OpenCV's C API rather than the C++ API. You can call C APIs directly from Objective C of course, so this makes life a lot easier. You just lose some of C++'s syntactic sugar, like default parameter values.

Related

Could opencv mix compile with Objective C for OS X app development?

I want to use OS X default GUI like NSImageView to show an OpenCV image for an OS X app(not iOS), so I need to use Objective C with C++, it's not a big deal for Apple LLVM compiler. But when it comes to OpenCV, even just to import opencv2/opencv.hpp in to a '.mm' file will crash the build.
I got the error:"Expected member name or ';' after declaration specifiers" in OpenCV utility.hpp line 'bool check() const;'.
I searched for this, I have a similar question here (Mix Objective-C and C++ and OpenCV). This problem is with some macro defined in both Cocoa and OpenCV. The answer is to import OpenCV header before Cocoa headers in '.pch' file.
By default an iOS template has a '.pch' file but OS X template don't. So I add a '.pch' with no luck, it won't compile either.
So my question is how can I do the same thing like the iOS solution? How can I get my OS X compile with OpenCV?
You can just import / include opencv headers directly in your source file when you need it, but make sure to do so before including Cocoa headers.
For example, I need to use OpenCV in ViewController.h so I did the following in ViewController.h:
#ifdef __cplusplus
#import <opencv2/core/core.hpp>
#endif
#import <Cocoa/Cocoa.h>
Now, here is the tricky part: you also need to be careful for files that depend on ViewController.h. Specifically, any other Cocoa files that import ViewController.h will need to import this file first thing (even before its own header, because its own header will import some Cocoa headers already).
I ended up doing something like this:
#ifdef check
#define OS_X_STUPID_CHECK_MACRO check
#undef check
#endif
#include <opencv2/core.hpp>
#ifdef OS_X_STUPID_CHECK_MACRO
#define check OS_X_STUPID_CHECK_MACRO
#undef OS_X_STUPID_CHECK_MACRO
#endif
What this does is save and undefine the offending macro before the preprocessor includes the header. Then, after the header is safely included--free of nonsense, I redefine the macro to what it was before.
The right answer is to define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 somewhere before everything else gets included. I put this in the Preprocessor Macros section of my Project's Build Settings.
Further explanation can be found in the usr/include/AssertMacros.h file:
For time immemorial, Mac OS X has defined version of most of these macros without the __ prefix, which
could collide with similarly named functions or macros in user code, including new functionality in
Boost and the C++ standard library.
A future release of Mac OS X will no longer do this, and will require that clients move to the
new macros as defined above. However, in the interim both the new and old macros will work, unless
clients define a macro __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES before this file is included
in their compilations. Clients who do not want the older macros defined can accomplish this by adding
#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
at the top of their sources, or my adding -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 to the
gcc compilation options.
I know it isnt the best way to solve this but I gave me root and edited the utillity.hpp from
bool check() const;
to
bool check(bool) const;
In my case everthing did work after that.

XCode cannot find #define macro in *prefix.pch but compiles OK

I've added something in -prefix.pch file, but XCode gives me error when I use it, saying
Use of undefined identifier ...
However if I compile it (Command+B), it compiles, so I thought it was caused by derived data, I then tried to remove derived data (thus to force it to be re-generated again) but in Organizer there was NO derived data for the project, I also tried Clean but does not work.
Can anyone help?
edit: the macro I defined is not important for the question, but here is the macro:
#define IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
edit 2: I added Kiwi as unit test tool to the project, probably something in project settings are changed which caused the problem.
as bbum says
Ewww… don't put macros in a .pch file! A .pch file is, by definition, a project specific precompiled header. It really shouldn't be used beyond the context of the project and it really shouldn't contain anything but #includes and #imports1
may be this helps
You will need to include inly framework related headers and also adding header in pch file means you need not import that header in any of the file in your project.
#import <Availability.h>
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif

Including C++ header files in Objective-C++ when they conflict with Objective-C macros

In Xcode, I've created a "Cocoa application" project. One of its dependencies is a framework containing C++ code. I renamed AppDelegate.m to AppDelegate.mm and included the framework.
The project fails to compile. The problem is that the C++ header files in the framework are using some symbols that conflict with Objective-C or Cocoa.
The C++ header files are defining functions called verify() and check(), which conflict with /usr/include/AssertMacros.h in the MacOSX10.8 SDK.
The C++ header files contain a variable called NO, which conflicts with the Objective-C macro NO.
A workaround would be to modify the C++ code in the framework to avoid these conflicts. But since it's a large C++ project maintained by another organization, this would take time and would possibly break in future updates of the C++ project.
Is there some way just to tell Clang/Xcode to treat those C++ header files as C++ instead of Objective-C++?
Reading through the /usr/include/AssertMacros.h that comes with Mac OS 10.8, it looks like you could do:
#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
before including AssertMacros.h, which will prevent it from defining macros called verify() and check().
Regarding NO: you could use the preprocessor to rename that variable for you. For example:
#define NO NO_libraryname_renamed
#include <libraryname.hh>
#undef NO
Depending on how the NO variable is used by the library, this might cause problems — if the header is declaring it as extern, then your Cocoa app will refer to it by the wrong name, and you'll get an undefined symbol error. But as long as you're not using that variable, and the library isn't depending on your app to define that variable, then you should be fine.
(And please file a bug report with the offending library, requesting that they rename their variable.)
Mixing several languages is calling for grief. Even more so mixing Objective C++ (itself a strange hybrid) with C++. Don't do it.

Xcode Project #include <cmath>

I'm trying to use code that already works in another standalone project without problems.
When I bring this code into my other final project, it indicate that 'cmath' file not found.
The file with the #include is in an .hpp file (it just defines some structs for opengl stuff), so there is not a corresponding .mm file. (This is C++ code and I'm mainly an objective-c user so not sure of all the c++ stuff)
But this is for opengl stuff and works fine we not in this project.
I've tried everything to make this work.
The final project with the problem has other code that uses #include without problems.
It is almost like something is causing xcode not to recognize the path the header anymore.
I've checked its file type it is "Default C++ header"
In the final project I'm using Zxing and also using CorePlots. Not sure if they are causing any problems. Also some file are using #include not sure if that could conflict with the #incude or not. (But again the other files with #include are working fine.
Any help will be greatly appreciated...
Alternately to Jon Reid's good advice you can pick "Compile as Objective-C++" in the Build Settings. (Search for "Compile sources" in the Build Settings window.) This is a little bit wild-west but is a quick way to see if the problem is in fact your C++ source compiling as C or Objective-C
Your header file doesn't exist by itself; something must import it. Rename the importing files, changing their file types from .m to .mm.
For example, let's say your header that includes <cmath> is named foo.h. And that this in turn is used by a bar module, composed of bar.h and bar.m. So foo.h is imported in either bar.h or bar.m.
Rename bar.m to bar.mm so that it uses C++. Do the same for all .m files that depend on foo.h.

How to make Xcode correctly find the headers, using the “User headers search paths”?

I'm trying to build a framework from libFLAC with Xcode, to use within my own Mac OS X application.
I use these FLAC sources:
http://sourceforge.net/projects/flac/files/flac-src/flac-1.2.1-src/flac-1.2.1.tar.gz/download
I only need a few of these source files but I'd rather keep everything untouched so I'm able to keep the original FLAC source if I want to I distribute the framework project with my own sources.
The flac-1.2.1.tar.gz contains these directories:
flac-1.2.1/include/
flac-1.2.1/src/libFLAC/
flac-1.2.1/src/libFLAC/include/
In order to build libFLAC, I've added the .c files from 'flac-1.2.1/src/libFLAC' into the project (as references). I also added the .h files.
The headers used in the source code are located in:
flac-1.2.1/include/FLAC/
flac-1.2.1/include/share/
flac-1.2.1/src/libFLAC/private/
For instance the sources code calls for the header are:
#include "private/bitmath.h"
#include "FLAC/assert.h"
#include "private/bitwriter.h"
#include "private/crc.h"
#include "share/alloc.h"
etc.
In Xcode, I've added these 'User Header Search Paths' to the the target Build Settings:
$(SRCROOT)/flac-1.2.1/include/
$(SRCROOT)/flac-1.2.1/src/libFLAC/include/
And of course, I've placed my flac-1.2.1 directory in the right place.
When I want to compile, the compiler doesn't find the headers file. I tried with GCC 4.2 and LLVM compiler 2.0. What am I doing wrong? Should I do something more?
I'm new into importing C sources in my otherwise all-ObjC project and I'd be happy to try whatever you throw at me. Just please avoid answering "If you can't do it, you shouldn't do it". I need to learn this and I will.
Ok I have the answer, it was really dumb. My Xcode Project folder path itself was containing a space character. The compiler doesn't like that ;)

Resources