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.
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 am trying to build my android application with support for OpenSceneGraph. I am trying to render a simple box from my project's raw folder. However, when I build the project I am getting this compile error in the FileUtils class of the OpenSceneGraph library:
Class 'stat64' doesn't have constructor stat64(const char *,stat64*)
Any ideas what is causing the problem?
I'm also faced with such problem when I have tried to compile OpenSceneGraph to Android. The problem is that NDK's <sys/stat.h> header for Android API less that 21 doesn't contain stat64 function definition so compiler thinks that stat64 is a struct. Problem can be solved by adding
#if defined(ANDROID) || defined(__ANDROID__)
#if __ANDROID_API__ < 21
#define stat64 stat
#endif
#endif
after src/osgDB/FileUtils.cpp:92.
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.
Does Android support pthreads?
And why when i use -pthread option i see the linker error:
i686-android-linux/bin/ld: cannot find -lpthread
#include <pthread.h>
#include <cxxabi.h>
extern "C" int printf (const char *, ...);
int main()
{
try
{
pthread_exit (0);
}
catch (abi::__forced_unwind &)
{
printf ("caught forced unwind\n");
throw;
}
catch (...)
{
printf ("caught ...\n");
return 1;
}
}
As far as I could see in the docs you do not need to use "-pthread". Checkout following:
http://mobilepearls.com/labs/native-android-api/#pthreads
Info from NDK offical docs states (android-ndk-r8\docs\system\libc\OVERVIEW.html):
PThread implementation:
Bionic's C library comes with its own pthread implementation bundled in.
This is different from other historical C libraries which:
- place it in an external library (-lpthread)
- play linker tricks with weak symbols at dynamic link time
So keep in mind that Bionic includes directly pthread as opposed to standard way you are used to (with -lpthread).
I have a core project which I'm building as a shared library. In one of the headers, I've defined a simple class shown below:
typedef pthread_mutex_t Mutex;
class CORE_API AutoLock
{
public:
AutoLock(Mutex& m);
~AutoLock();
private:
AutoLock();
AutoLock(const AutoLock&);
AutoLock& operator=(const AutoLock&);
Mutex m_Mutex;
};
where CORE_API is defined as:
#ifdef CORE_DLL
#define CORE_API __attribute__ ((dllexport))
#else
#define CORE_API __attribute__ ((dllimport))
#endif
In the Android.mk for core, I've defined CORE_DLL under LOCAL_CFLAGS. However, when building, I get the warning:
warning: 'dllimporot' attribute directive ignored
When ndk-build gets to the other project where I want to use the AutoLock class, I get the error:
error: 'AutoLock::AutoLock()' is private
error: within this context
Why would the compiler ignore the dllexport attribute? I would hope that once that's fixed, my other project should build and be able to use the AutoLock class without any problems.
Shared libraries are created differently on Android (Linux) than with Windows.
In Windows you have the special dllimport and dllexport directives but not on Android (Linux).
When using your shared library, you should just compile with -lYourLibraryName
This might help you: http://www.adp-gmbh.ch/cpp/gcc/create_lib.html
Have a look at the sample code available in the android-ndk, specially the Android.mk file this might solve your problem.