Using C++ in swift using a Objective-C Wrapper - c++

I want to build a little project that utilizes the QR Encoder. I simply used Cocoapods to install it within my project and included the QREncoder.h file within my bridging-header, which works just fine for a couple of other Objective-C resources. My problem occurs because I am including the QREncoder.h file which the includes the QR_Encode.h file. This file uses a pretty standard C++ class definition class CQR_Encode{...};, but when I'm trying to compile my code now, I get the following error /PATH_GOES_HERE/Pods/QR-Code-Encoder-for-Objective-C/QRCodeEncoderObjectiveCAtGithub/QR_Encode.h:81:1: Unknown type name 'class'; did you mean 'Class'?. Looking for that error on the internet got me the information, that I need a Objective-C wrapper class for that file, but I thing QREncoder{.h,.mm} should do the job. I also changed file type within the attributes inspector to either 'objective-c++ source' or 'c++ header' but that did not change the error. I also tried setting the 'compile sources as'-setting in build settings, but of course this didn't work since it sets the compile type for all files and since there are Objective-C classes, it won't work. Does anyone have an answer to help me out?

Related

Import .tlb, Generated .tlh Gives: forward declaration of enum type is nonstandard

I'm reusing a code I wrote couple years ago on a different version of Visual Studio, now Im trying to do it in VS 2017. The code aims to connect different applications using server-client arrangement.I'm accessing the .tlb of one application but I cannot establish the connection (either error of non-accessible .tlh or just no identification of different application methods/properties) , among 254 others.
The question is similar to this one: Import .TLB file gives "cannot open source file x.tlh"
I have tried adding the .tlb file in additional library directories but even when the error disappears, the code still doesnot recognize many methods that were fine before. #import statement shows no errors, yet the generated .tlh file has the following error:
forward declaration of enum type is nonstandard
Hence, It doesnot compile
Other issues also appeared, such as this:
no instance of function template "IID_PPV_ARGS_Helper" matches the argument list
for this line:
HRESULT hr = hyStream->QueryInterface(IID_PPV_ARGS(&Strm));
Now, the whole project was running seamlessly back then. I copied three classes with their headers to a new project, so maybe dependencies are the source of errors? Should I add .tlb file in library dependencies of the project?
Any comment is highly appreciated..

What do I need to do to get cocoapods to build with C++?

I'm trying to build a library to distribute via Cocoapods. The library is written mainly in Objective C, but includes a few C++ files. None of the C++ headers are part of the library's public API. The library builds fine in Xcode, and I can distribute as a framework, but a pod is probably easier for others to consume, right?
This is my first time attempting to build a cocoapod, so I may be doing something obviously wrong.
When I run pod lib lint or try to build the demo app that depends on the pod, I get error messages that suggest that the build system doesn't understand C++ at all.
in a C++ header file:
class CGuard {
> unknown type name 'class'; did you mean 'Class'?
in another C++ header file:
template<typename T>
class CContexts {
> unknown type name 'template'
My podspec file includes
spec.xcconfig = {
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++11',
'CLANG_CXX_LIBRARY' => 'libc++'
}
spec.library = "c++"
What else can I do to tell the build system to use the C++ compiler?
It looks like the key was adding private_header_files entries to remove the C++ headers from the framework that Cocoapods exports.
Although Cocoapods is documented to only include the files from public_header_files in the generated module umbrella header, it looks like each subspec section has all of its headers included if that subspec section doesn't have its own public_header_files entry.
The C++ files were all compiled in a subspec section to let me use different compiler settings, so the private_header_files entry needed to be inside that subspec section as well.

How to use Superpowered lib in Swift project

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>

how can I create an extension for Qt application

There is this guide: http://qt-project.org/doc/qt-4.8/plugins-howto.html
It is totally useless, because it is missing too many crucial information. However after few hours of some research I figured out how to get somewhere:
Source code of interface .h: https://github.com/huggle/huggle3-qt-lx/blob/master/huggle/iextension.h
And .h of plugin: https://github.com/huggle/extensions/blob/master/c%2B%2B/HelloWorld/HelloWorld/helloworld.h
I managed to create an interface for plugin and applied the macro to it, then I created a plugin but as in example the plugin should be inherited from interface, I clearly need to somehow include the .h file from my project. I did that, and then I used QPluginLoader in order to load the .so file.
However I am getting this:
Failed to load (reason: Cannot load library /home/petanb/Documents/huggle3-qt-lx/huggle/extensions/libHelloWorld.so: (/home/petanb/Documents/huggle3-qt-lx/huggle/extensions/libHelloWorld.so: undefined symbol: _ZTIN6Huggle10iExtensionE))
that makes sense, the library (where I #include the .h file of my project) is clearly missing the reference to binary of my application in order to resolve it but how can I give it to that? Should I copy the application's binary, rename it to something.so and put it to /lib or something? Or what should I do?

can I call an app in OpenFrameworks something other than testApp?

I am working with OpenFrameworks for the first time (I am also rusty at C++).
I am trying to build an app with OFX, and I want to call my app something other than testApp. I am building off the openCVExample code, and I've replaced testApp everywhere with the new name and moved the files from testApp.{h,cpp} to newname.{h,cpp}.
However, when I try to build (using Microsoft Visual C++ 2010 Express, if that makes a difference) I see that the testApp.cpp file is being generated with the contents of newname.cpp and put into my src/ folder. I'm also getting griped at by the build saying that testApp isn't a valid namespace on all lines in newname.cpp where I am trying to call or define member functions (I am using newname::functionName).
I've looked at the build commandline, and it doesn't seem to be looking for testApp.cpp; I've also looked through the linker and other stuff, but don't see it mentioned anywhere in there. Is this some bizarre feature of OpenFrameworks?
In the openframeworks directory there is a project creator app that will do this for you.
D:\workspace\of_v0073_vs2010_release\projectGenerator\projectGenerator.exe
It will also setup addons you've downloaded.
Note:: It creates solutions for VS 2010, i assume this can be opened by Express?
You'll need to change the instances of "testApp" to "newname" in a handful of places:
In testApp.h you'll need to change your app's class name. This is probably the 5th line, which looks like class testApp : public ofBaseApp
In testApp.cpp, you'll need to change all of the function definitions to use the "newname" namespace. These are all of the lines which look like void testApp::setup()
In main.cpp, you'll need to change the argument in ofRunApp() from new testApp() to new newname()
You actually don't have to change the names of the files from testApp.{h,cpp}, though it's still a good idea from an organization standpoint.