I'm trying to implement biometric authentication on iOS from a C++ codebase. Here is one example.
In order to achieve this, I need to use the LAContext obj-c APIs. However, when I try to initialize the class from C++ I get a pointer/reference error:
// Cannot initialize a variable of type 'LAContext *__strong' with an rvalue of type 'LAContext'
LAContext* authContext = LAContext();
Is there any way to achieve this? Or is this struct available from Obj-c only?
Edit 1:
My file is in Obj-C++, so in theory I should be able to mix C++ and Obj-C code, however when I try to write a Obj-C function to alloc the LAContext object I get a missing symbols error:
-(bool)biometricsAvailable {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
return true;
}
On the compilation step this error is thrown:
Undefined symbol: _OBJC_CLASS_$_LAContext
XCode itself does not show any error while editing the file, only happens when I try to build/compile the app.
As it turns out, the problem was not with mixing C++ and Obj-C code, but rather with my library being linked via cocoapods and the LocalAuthentication framework being missing.
I needed to add:
s.frameworks = "LocalAuthentication"
to the podspec and creating a LAContext instance works just fine.
Related
I need to use a library in my C++ project that needs to call an extern function:
SetGameViewController(UIViewController* gameViewController)
I have zero knowledge of Objective C and iOS yet. I need to get UIViewController and pass it to that function.
So this code should get the UIViewController:
UIWindow *window = [UIApplication sharedApplication].keyWindow;
UIViewController *rootViewController = window.rootViewController;
I also added this import:
#if defined(OS_IPHONE)
#import <UIKit/UIKit.h>
#endif
I get compiler errors like:
Expected unqualified-id
Unknown type name 'NSString'
I've started learning Objective C and read a few articles but couldn't get much further than that yet.
So basically my question is how do I basically import and use Objective C code in C++ code so that I can get and use the UIViewController?
Easiest way will be to rename your source file with the extension ".mm" - it will then be compiled as objective-c++, which means you get all the wonders of c++ while still being able to interact with objective-c objects (counted pointers to things 'derived' from NSObject).
I'm a beginner with Xcode...
I'm trying to use openCV c++ with Scenekit=> to make an AR scene.
Well, I was too optimistic.
1/I started to use the default XCode template for game.=> works!
2/openCV without scenekit=> works
3/ mixing...
I imported some c++ headers in the gameviewController file (basically a UIViewController with scenekit inside).
If I let it so, I get compiler error (cstddef not defined). Fair enough, it's C++ so, from what I read, I just have to rename .m to .mm
But, in this case, I get a full list of linker errors such as Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_SCNAction", referenced from:
=> I guess it is more tricky to mix objective C and C++ but on a simpler project, without Scenekit but with a very similar code otherwise, it worked nicely.
Any clue or guide for mixing them? Should I use swift?
Thanks a lot,
Michael
I just need to add "SceneKit.framework" to Link Binary With Libraries:
Same problem here. I had a pure Objective-C class, simply named "GameViewController.m". To turn it into an Obj-C++ class, change the ".m" to ".mm".
However, just by changing the extension, the linker spat back 13 undefined symbols....
"_OBJC_CLASS_$_SCNTransaction", referenced from: ...
"_OBJC_CLASS_$_SCNFloor", referenced from: ...
"_OBJC_CLASS_$_SCNMaterial", referenced from: ...
etc...
To get around this, just create a different (new) Obj-C++ class, with a .mm extension, and place your C++ code in that class.
Now you can instantiate that new class from the class containing SceneKit calls and call the methods in the new Obj-C++ class.
Inside the GameViewcontroller.m class:
...
scene = [SCNScene sceneNamed:#"art.scnassets/grid.dae"];
kinematics = [[KinematicScene alloc] init];
[kinematics setupCharacters];
...
And inside the new Obj-C++ class (KinematicsScene.mm)
#implementation KinematicScene
{
AI::Location *location;
}
-(id) init
{
self = [super init];
if( self )
{
AI::KinematicSeek* seek = new AI::KinematicSeek[2];
location = new AI::Location[2];
}
return self;
}
-(void) setupCharacters
{
.....
}
... etc ....
#end
This worked for me:
Disable module support [CLANG_ENABLE_MODULES, -fmodules]. This has user experience downsides. Read the online help for this setting before disabling it, and also be aware that if you disable it you will become responsible for hunting down the libraries and frameworks you need to link against, and this can be tedious if you are not an old hand.
Build and (attempt to) link. Add the frameworks and libraries you need to resolve the link errors. I recommend creating a group in your project and directing it to your SDK, then adding the frameworks and libraries relative to that SDK.
I'm trying to intercept some native library-calls via LD_PRELOAD.
This is working fine for simple libraries written in C, but now I try to go further and override some more complex class-methods from the AOSP written in C++.
Here's my example:
#include <rs/cpp/util/RefBase.h>
namespace android {
sp<MediaCodec> MediaCodec::CreateByType(const sp<ALooper> &looper, const char *mime, bool encoder) {
// TODO this will be implemented by me
return NULL;
}
}
In my Application.mk, I got the following piece of code:
APP_STL := gnustl_static
and inside the Android.mk this one:
LOCAL_STATIC_LIBRARIES += libstlport_static
Sadly, the error I get is the following:
jni/libhook/ld_preload.cpp:88:1: error: 'sp' does not name a type
Anyone an idea how to use sp<..> here? I assume it's not Android-specific but a standard C++-thing - I'm totally new at C++, just started "today" :)
I know this may be bad practice, so I'm welcome for any other idea.
sp<> is Android-specific. sp<> is Strong Pointer, wp<> is Weak Pointer; they came into being as part of the Binder IPC implementation.
The place to start looking for the implementation is the framework RefBase.h, which is a bit twisty for a C++ newcomer. None of what you're fiddling with is part of the public API defined by the NDK, which means it's subject to change between releases, so be aware that what you're trying to do may not work across devices or software updates.
I'm creating a C++ level event emitter addon for node.js. I'm getting this C++ error when including the add-on in a node.js project.
Non-function in MakeCallback. method = emit Abort trap: 6
I found this Gist with a simplified example of the same behavior:
https://gist.github.com/jedi4ever/4250746
Hoping for some general insight into why this might be caused or what this error means.
If I understand what you're trying to do correctly, you have a couple of problems in your keylogger.js file;
util.inherits(new keylogger, events.EventEmitter);
exports = keylogger;
You're trying to extend an instance, and your export statement is a bit off. This should work better to export keylogger as an instance which the test file seems to expect;
util.inherits(keylogger, events.EventEmitter);
exports.keylogger = new keylogger();
I am trying to use an ActiveX control in my program.
QAxWidget* mAX = new QAxWidget();
mAX->setControl("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}");
I know that there is a function:
put_ChannelType(long newValue)
But when I try to execute it:
mAX->dynamicCall("put_ChannelType(long)",2);
mAX->dynamicCall("put_ChannelType(int)",2);
mAX->dynamicCall("put_ChannelType(long)",QVariant(2));
mAX->dynamicCall("put_ChannelType(int)",QVariant(2));
I get:
QAxBase: Error calling IDispatch member put_ChannelType: Bad parameter count
Any idea what is going wrong ?
EDIT:
Weird thing is if I call
mAX->dynamicCall("put_ChannelType()");
I do not get any error message...
EDIT 2:
This also fails (as Constantin suggested)
QList<QVariant> varlist;
varlist << (int)1;
mAX->dynamicCall("put_ChannelType(int)",varlist);
Got this solved using the generateDocumentation() function.
I was using this ActiveX control in another application, but an MFC one.
It seems the function names I was referring to (which were in a machine generated IDispatch wrapper class created by VS) were not the same as the ones Qt listed.
i.e. put_ChannelType is actually SetChannelType...
Maybe this is just a version issue ?
Anyways, important part is knowing that generateDocumentation() can list you all the functions you can call with dynamicCall.
Is it OK?
mAX->dynamicCall("put_ChannelType(const QVariant &)", (long)2);