In an iOS Swift project I'm including a set of libraries built using C++ (HikVision/hcnetsdk.h) and while I've managed to get the frameworks to build, the header file won't compile and Xcode is giving me multiple 'C does not support default arguments'.
For example on this line:
NET_DVR_API BOOL __stdcall NET_DVR_SetConnectTime(DWORD dwWaitTime = 3000, DWORD dwTryTimes = 3);
I've checked the build settings of the project and as far as I can tell everything is set to use C++, so I'm confused as to why Swift is compiling this as C, and complaining about default arguments.
My bridging header file is as follows:
#import "ldapTest.h"
#import "hcnetsdk.h"
#import "HikDec.h"
I'm fairly sure it's a build setting somewhere but which one I don't know.
So it turns out you can't include a C++ header file which contains C++ specific keywords into a Swift bridging header file.
What I did manage to do for my specific situation was find a "C" replacement of the "C++" header which worked with a few minor tweaks.
This is the "C" header file for the HikVision HCNetSDK.h which I found online:
https://github.com/shulianghe/new-project/blob/master/pro/hcSrc/incCn/HCNetSDK.h
If anyone has a similar problem with other C++ header files, you can copy some of the #ifdef __cplusplus statements in the link above to see how it's done.
Related
I've been creating a UI toolkit to use on MacOS and Windows, but im currently working and testing the MacOS side of things. Recently, when im compiling my code, using CMake, I get an unreasonable amount of errors from including the Cocoa header. Here is a ghostbin of the errors.
I'm not sure if this is a complete answer to your question, but hopefully it gives you a path forward. Thanks to #uliwitness for mentioning #if __OBJC__.
So QT5 has a git repo for qmacextras, which combines c++ and objective-c, something I am doing and how I was seeing a bunch of errors when importing <Foundation/Foundation.h> or <Cocoa/Cocoa.h>. Looking at some of their code, I saw this:
// ### remove when merged to QtCore
/*!
* \macro Q_FORWARD_DECLARE_OBJC_CLASS(classname)
*
* Forward-declares an Objective-C class name in a manner such that it can be
* compiled as either Objective-C or C++.
*
* This is primarily intended for use in header files that may be included by
* both Objective-C and C++ source files.
*/
#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
and
// Put in your header file
Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
Q_FORWARD_DECLARE_OBJC_CLASS(NSImage);
// etc
https://code.qt.io/cgit/qt/qtmacextras.git/tree/examples/macextras/macfunctions?h=5.14
Using this might negate those errors.
You're not really asking a question... but from a casual glance at what little information you provide, it looks like there is ObjC code being run through a non-ObjC compiler.
This usually happens when someone includes an ObjC header from a C or C++ source file. A very common way of causing this is to add a precompiled header to your project that includes Cocoa/Cocoa.h. A precompiled header is used for all C-descended languages you compile, so also for C or C++ files.
To avoid ObjC-specific code from being included in non-ObjC files, wrap it in #if __OBJC__ preprocessor macros. (This also applies to C++ code in your precompiled header, which you'll want to wrap in #if __cplusplus)
I'm trying to integrate C++ code (fuzzylite.com) into a Swift framework project and I keep receiving build errors. From what I understand, you cannot use a bridging header in Swift framework projects, rather you need to include the source in the Umbrella headers. I wrapped the C++ code in Objective-C classes and then included the Objective-C headers in the umbrella header as such:
#import <Fuzzylite/ObjCWrapper.h>
Followed all the steps as mentioned here (Clarification on adding Objective C code to a swift dynamic framework) but it doesn't really work because it is not able to find the Objective-C wrapped C++ framework. Any help is highly appreciated!
Solved it by doing the following:
Added C++ source directory into XCode project
Expose C function wrappers to C++ instance methods
Created C header file wrapper for the C++ project like such:
#ifndef Header_h
#define Header_h
#ifdef __cplusplus
extern "C" {
#endif
void hello(char *str);
#ifdef __cplusplus
}
#endif
#endif /* Header_h */
In the Umbrella header file (in my case the name of the Umbrella header file was 'TestSDK.h') for the framework project (remember that since this was a framework target, there was no bridging header involved as is the case when building an app), I put the following.:
#ifdef __cplusplus
#import "fuzzylite/fl/Headers.h"
#endif
Added the -I/ to XCode->Target->Build Settings->Other C Flags. In my case, the path was:
-I$(PROJECT_DIR)/TestSDK/fuzzylite/
This worked for me. Without step 5, I was getting path include errors.
When I try to call the functions in my C++ implementation file (marked as C compatible in the header with the #ifdef __cplusplus extern "C" {} trick), I am getting the error:
"use of unresolved identifier, 'helloWorld()'"
I created the bridging header just by adding a cpp and header file to my project and clicking "OK" when it asked if I wanted to create the bridging header. I am #including "test.h" in the bridging header, which has the function declaration inside, but for some reason Swift just cannot see the function.
The weirdest part is, I created a new project and did the EXACT same procedure, and calling helloWorld() works fine, so it's something about the existing project I'm trying to add the cpp file to that isn't working.
I'm assuming then that this is a build-settings problem, and that I must have messed them up somewhere along the lines, probably when I was trying to import a static C/CPP library (Which I've since removed, but some of the build settings I changed for it probably stayed).
So are there any build settings I should know about that will fix this? Or is there a way to just completely reset my build settings to the default (Even if that means I have to recreate the bridging header to get the bridging header build settings back in place)?
Thank you for any and all help!
James
---Edit---
Here is my cpp header:
Here is my cpp implementation file:
Here is my bridging header:
Here is the relevant portion of the Swift project:
And here is the build setting that sets the bridging header:
Alright - This has been resolved. The problem is that the bridging header needed to be realized from both the regular target and also the Testing target, which was in my existing project because I'm doing Unit Testing.
I simply went into the build settings for my testing target and added the appropriate Objective-C Bridging Header, and then it all worked fine.
Hope it helps someone!
I had the same experience. Make sure you add a Unit Test Target, then ensure the Unit Test Target has visibility of the Bridging Header file.
Another mistake I made; ensure each Swift Class, Enums used in the test case has Target Membership set correctly.
I'm getting include not found compile error in XCode. I have an iOS app project that i use Objective-c and c++ as mix.
Initially, i created one .h file and one .cpp file in my ios project. Then, I renamed the .cpp file to .mm file.
Here is my .h file;
TestLog.h
#ifndef CalculatorDemo_TestLog_h
#define CalculatorDemo_TestLog_h
#include <string>
using namespace std;
class TestLog
{
private:
string logString;
public:
void Log(string logMessage);
};
#endif
TestLog.mm
#include "TestLog.h"
void TestLog::Log(string logMessage)
{
//this->logString->append(logMessage);
}
What am I missing? Do I need to add std c++ library to my targetS? Something related to Search Header Paths?
I just need to use string type.
Thanks much for in advance
select project -> build setting -> apple LLVM compiler 5.1 -> language
In Compile Sources As change to Objective-C++
There's a quirk in XCode. I noticed it in 7.3. Most projects recognize .mm files and the STL, while one project I had did not. The fix was that I had to click on the top-left project icon, then click Targets > Build Phases > Link Binary with Libraries > and add in AppKit.framework. Next, I had to click Targets > Build Settings > search on "Compile Sources", and set it to "Objective C++" on all possible columns. Then, do a Clean and then a Build from the Product menu. This compiled properly then. Then, go back to that Compile Sources again and set it back to "According to File Type" on all possible columns. Then, click Build from the Product menu again. At that point, it compiled properly and allowed me to utilize the "according to file type" option, which I like better.
Oh, and if doing Cocoa stuff, don't forget to add the following header in your files:
#import <Cocoa/Cocoa.h>
And if doing command line stuff, don't forget to add the following instead of the Cocoa header:
#import <Foundation/Foundation.h>
i believe you need to include the whole path to the library. similarly to say "foundation" & "uiview" frameworks.
#import <Foundation/Foundation.h>
or
#import <UIKit/UIKit.h>
and yes, make sure you add the library to your target.
So I was having this issue with the Cocoapods library Bypass and none of these solutions did anything. The problem was with a file which Cocoapods creates called an umbrella header. This is located in <POD_NAME>/Support Files/<POD_NAME>-umbrella.h. Delete it, and it should build just fine.
Now for the explanation of why this is necessary: the umbrella header is mixing both C++ and Objective-C code directly in a header which is a big no-no apparently and ends up completely breaking the C++ imports. By removing it (which seems to have no effect?) this conflicting import which Cocoapods unknowingly created will go away.
Ran into this with xcode 12.4 with a project that is objective-c, but where I need one C++ modul. Solution: wrap the contents of the .h file in:
#if defined __cplusplus
declarations
#endif
Apparently xcode is not good at detecting a mix of sources.
see Expected ; after top level declarator, error in xcode
This often happens when Xcode doesn't understand that a C++ header file you've imported into Objective-C is actually for C++ code.
So you can solve this problem by finding the Objective-C file that imports C++ code, and simply change its extension from .m to .mm
I've been using a C++ library without problems on projects built with Xcode 3, but I'm now getting build problems on projects built with Xcode 4.
Drop the library into the Xcode 4 project and it builds fine, but as soon as I #include it, I get a "Lexical or Preprocessor Issue" error, more specifically " 'string' file not found, on line 4 of its main header file.
On closer inspection, the error specifies that 'string' file not found in ~/my project's directory/include/mainheader.h
I've tried the solutions listed here, but none worked.
So it thinks that header file is in my project directory, but it's obviously a C/C++ header… How can I tell Xcode to look for these C/C++ headers?
The problematic #include was at the top of my ViewController.mm, which I had already turned into Objective-C++ by giving it .mm as its extension. But ViewController.mm gets eventually imported by AppDelegate.m, which is Objective-C by default – and I had forgotten to make it Objective-C++, hence the problem.
So renaming AppDelegate.m to AppDelegate.mm solved the problem.
I think #include is a c++ class template..so you need to used using namespace std in your header file and also rename your source file .m format to .mm format.
it works for me :) try this...