I am trying to port the following piece of C++ code to Android as part of some NDK work:
#include <fstream>
// ...
inline void trim(string & str, const string & delim = " \t\r\n")
{
string::size_type pos = str.find_last_not_of(delim);
if(pos == string::npos) str.erase(str.begin(), str.end());
else
{
str.erase(pos+1);
pos = str.find_first_not_of(delim);
if(pos != string::npos) str.erase(0, pos);
}
}
What I get is the following message at str.erase(pos+1); and str.erase(0, pos):
Invalid arguments '
Candidates are:
std::basic_string<char,std::char_traits<char>,std::allocator<char>> & erase(?, ?)
__gnu_cxx::__normal_iterator<char *,std::basic_string<char,std::char_traits<char>,std::allocator<char>>> erase(__gnu_cxx::__normal_iterator<char *,std::basic_string<char,std::char_traits<char>,std::allocator<char>>>)
__gnu_cxx::__normal_iterator<char *,std::basic_string<char,std::char_traits<char>,std::allocator<char>>> erase(__gnu_cxx::__normal_iterator<char *,std::basic_string<char,std::char_traits<char>,std::allocator<char>>>, __gnu_cxx::__normal_iterator<char *,std::basic_string<char,std::char_traits<char>,std::allocator<char>>>)
'
I tried what was suggested here but it did not help. Instead, now I am getting a new message for #include <fstream>:
Unresolved inclusion: <fstream>
What do I need to do to resolve this? Thank you.
UPDATE: I am trying to add this piece of code to an existing C++ code in an Android project that built and ran fine. When I applied the change linked to above, I not only got the unresolved inclusion for fstream, I also got a bunch of other errors. For instance, for the following block form the existing code:
#include <jni.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <vector>
I am also getting Unresolved inclusion errors. So it made things worse.
Try to add the following line to Application.mk of your project.
APP_STL := gnustl_static
Related
I seem to not find any documentation about android service wrappers and I'm stuck with "use of undeclared identificator "TJBatteryManager".
#include <Androidapi.Helpers.hpp>
#include <Androidapi.JNI.Telephony.hpp>
#include <Androidapi.JNI.Os.hpp>
...
int TGlobal::getBatteryLevel(){
_di_JObject BatterObj = SharedActivityContext()->getSystemService(TJContext::JavaClass->BATTERY_SERVICE);
return TJBatteryManager::Wrap(((_di_ILocalObject)BatterObj)->GetObjectID())->getIntProperty(BATTERY_PROPERTY_CAPACITY);
}
I found this syntax on some code samples and the project i'm working on already use this same process with TELEPHONY_SERIVCE and TJTelephonyManager::Wrap.
Am I the one that has to create this TJBatteryManager somewhere ?
I don't find any reference of TJTelephonyManager anywhere else than in this class tho.
Same thing about _di_JXXXX types. _di_JObject and _di_JTelephonyManager are used in my project and it seems they just come from the Androidapi includes, so why is it telling me _di_JBatteryManager does not exist ?
I have the following program working correctly in ideone
#include <iostream>
#include <regex>
using namespace std;
int main() {
if (regex_match("test", regex("^[_a-z0-9]{3,12}$"))) {
cout << "match" << endl;
} else {
cout << "no match" << endl;
}
return 0;
}
It matches as expected. Just checking for a string containing between 3 and 12 alphanumeric characters or underscores.
However, the same code run in native code on Android (built using ndk-build with gnustl_shared) fails (does not match).
If regexes aren't properly supported under Android, shouldn't my build fail to compile? Am I missing something obvious here?
I have the same issue today,
and in my own experience, just change the "_" position in the expression.
for my example,
just replace
std::regex reg("[^. _A-Za-z0-9]");
with
std::regex reg("[^. A-Za-z0-9_]");
and it works fine, maybe it is because the gcc version is too old.
I'm building a jni lib for android using NDK, I need to change pipe buffer size, but fcntl(pipe_fd[0], F_SETPIPE_SZ, 1048576);
compiling failed, errror message "F_SETPIPE_SZ undelcard", I already added #define _GNU_SOURCE at the beginning of the C++ source file. What could be the reason?
I'm guessing your problem is that you never ended your #ifndef for _GNU_SOURCE, since you state that you have included it at the beginning. Here is an example of what your files should look like that need access to that macro:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <fcntl.h>
extern "C"
{
int test()
{
int some_fd = 123456;
int size_in_bytes = 12345;
return fcntl(some_fd, F_SETPIPE_SZ, 12345);
}
} // End extern
#endif
Checked against the following versions
Android Studio: 1.3.2
NDK: r10e
Various gradle settings:
compileSdkVersion 22
buildToolsVersion "23.0.0 rc3"
I am very much new to cocos2dx. I have a cocos2dx project made in xcode. for gesture recognizers I used cocoa touch's native code(UIGestureRecognizers) in cocos2dx using .mm files.
Now I want to build this project with android sdk too.
The Error i am getting by building the android project using build_native.sh file, in terminal is Like The Following
1
../android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/cocos2dcpp_shared/__/__/Classes/HelloWorldScene.o: in function HelloWorld::menuCloseCallback(cocos2d::CCObject*):jni/../../Classes/HelloWorldScene.cpp:88: error: undefined reference to 'XBridge::doSth()'
2
../android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/cocos2dcpp_shared/__/__/Classes/HelloWorldScene.o: in function HelloWorld::menuCloseCallback(cocos2d::CCObject*):jni/../../Classes/HelloWorldScene.cpp:85: error: undefined reference to 'XBridge::imageName'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libcocos2dcpp.so] Error 1
make: Leaving directory `../cocos2d-x/projects/MyGame/proj.android'
What Am I missing Here ? I just started learning cocos2dx.
Can i even use the native iOS code like this in an android project ? or i am just shooting blanks ?
My Code is as written below.
CODE IN MY HelloWorldScene.cpp
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
#else
cocos2d::CCString * imageNameString = cocos2d::CCString::create("image.png");
XBridge::imageName = imageNameString->getCString();
XBridge::doSth();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
//exit(0);
#endif
#endif
}
Code In XBridge.h
#ifndef xbridge_XBridgeViewController_h
#define xbridge_XBridgeViewController_h
#include "cocos2d.h"
class XBridge {
public:
static std::string imageName;
static void doSth();
};
#endif
Code In XBridge.mm
#include "XBridge.h"
#include "AppController.h"
#include "RootViewController.h"
#include "SpriteVC.h"
using namespace cocos2d;
std::string XBridge::imageName;
void XBridge::doSth()
{
id sth = [[UIApplication sharedApplication] delegate];
if ([sth isKindOfClass:[AppController class]])
{
printf("XBridge::doSth imageName %s\n",imageName.c_str());
SpriteVC *SPVC = [[SpriteVC alloc] initWithNibName:nil bundle:nil];
SPVC.imageNameString = [NSString stringWithFormat:#"%s",imageName.c_str()];
[SPVC setUpImage];
NSLog(#"XBridge::doSth imageName == %#",[NSString stringWithFormat:#"%s",imageName.c_str()]);
//SPVC.imageView.frame = CGRectMake(480, 320, 333, 333);
AppController *controller = (AppController *)sth;
[controller.viewController.view addSubview:SPVC.photoImage];
}
}
You can't use iOS Cocoa Touch API for Android even though you actually can compile Objective-C and Objective-C++ code using Android NDK Clang toolchain. Because Android NDK doesn't provide iOS API at all like UIApplication, AppController, and so forth. Cocos2d-x just provides Cocos2d-x API in C++ and some plugins for Android.
If you want to use iOS API for Android, take a look at Apportable.
I have a simple file stlTest2.cpp like this:
#include <jni.h>
#include <cmath>
bool isnan (void);
There is something more complicated in some code I am porting. My question is this. Why would this work when building using GCC outside of the NDK, but not with using the NDK? There error it gives is this:
jni/stlTest2.cpp:6: error: expected unqualified-id before 'sizeof'
jni/stlTest2.cpp:6: error: expected ')' before 'sizeof'
The immediate reason for this is that math.h (included via <cmath>) defines isnan as a macro. Why is the build outside of the ndk not including the #define from math.h, but this is? If I comment out the includes in the code, all is fine, but that is not acceptable as this problem repeats itself.... a lot.
The isnan macro was added in C99. In C++11 it was added as a function in the std namespace, overloaded for float and double and long double (so a typical <cmath> header, such as your non-NDK GCC is probably using, might have something like this:
#undef isnan
inline bool isnan(float ...) { ... }
inline bool isnan(double ...) { ... }
inline bool isnan(long double ...) { ... }
), but apparently the NDK hasn't gotten the memo, and is still providing the C99 macro as a convenience. (isnan was never a macro in C++, but before TR1 added std::tr1::isnan, there wasn't really a C++ alternative, so multiple C++ compilers provided the C99 macro.)
Do you need to be able to use the compiler-provided isnan or std::isnan? If not, then you can just change this:
#include <cmath>
to this:
#include <cmath>
#undef isnan
(and similarly for any other problematic macros, provided you don't need them).
In $ndk\sources\cxx-stl\gnu-libstdc++\libs\armeabi\include\bits\c++config.h (change armeabi to whatever is appropriate) change this:
/* #undef _GLIBCXX_USE_C99_MATH */
to
#define _GLIBCXX_USE_C99_MATH 1
Then clean and build your project again.