I've written a basic game using Cocos2D-x. It works fine on the iPhone. Now I'm trying to port it to Android. When I run the script, it gives me the following error:
jni/../../Classes/MemoryModeLayer.cpp: In member function 'void MemoryModeLayer::startNewGame()':
jni/../../Classes/MemoryModeLayer.cpp:109:25: error: 'time' is not a member of 'std'
jni/../../Classes/MemoryModeLayer.cpp:109:25: note: suggested alternative:
/Users/abc/android-ndk-r9d/platforms/android-8/arch-arm/usr/include/time.h:40:17: note: 'time'
jni/../../Classes/MemoryModeLayer.cpp:111:5: error: 'random_shuffle' is not a member of 'std'
jni/../../Classes/MemoryModeLayer.cpp:112:5: error: 'random_shuffle' is not a member of 'std'
make: *** [obj/local/armeabi/objs/cocos2dcpp_shared/__/__/Classes/MemoryModeLayer.o] Error 1
make: Leaving directory `/Users/anil/cocos2d-x-2.2.3/projects/Game/proj.android'
In MemoryModeLayer.cpp I have the following:
std::srand(unsigned(std::time(0)));
std::random_shuffle(_xCod, _xCod + _numberOfRows);
std::random_shuffle(_yCod, _yCod + _numberOfColumns);
I've included the following headers as well:
#include <string>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <iomanip>
Also added using namespace std in the header file. Is there anything else that I should do?
you need to #include <random>
There was a problem with the Application.mk file. Had to change the STL library lookup like so:
Add APP_STL := stlport_static to the Application.mk file. It may already have APP_STL := gnustl_static.
Following blog post was very helpful!
http://blog.codetactics.com/2013/06/05/porting-a-cocos2d-x-ios-game-to-android/
Related
I have a C++ project compiled in a shared library. I need to use that library (.so file) in Android with the NDK.
The idea is that someone else would compile the C++ project and give me the .so file, so that I don't have to compile it on my computer.
I need to reference the .so file in my Android.mk file, and all the solutions I tried did not work. That's where I'm stuck.
So:
is it possible to do what I described without creating one shared library per platform?
how can I reference my .so library in my Android.mk? All the solutions I tried did not work.
To reproduce everything from scratch, I did these steps:
1°) Create a HelloWorld C++ project:
Test.h:
#include <iostream>
class Test {
public:
Test();
~Test();
static std::string getTest();
};
Test.cpp:
#include "Test.h"
std::string Test::getTest()
{
return "Hey!!\n";
}
2°) Create the shared library:
g++ -Wall -shared -fPIC -o libTest.so Test.cpp
This gaves me a libTest.so file, which I can use on a C++ project. Now I want to use it on an Android project.
3°) Create a basic empty Android project:
package: com.so.test
name: CppTest
4°) Create a "Test.java" file next to the MainActivity.java file containing:
package com.so.test;
public class Test {
static {
System.loadLibrary("hellondk");
}
public native String getMessage();
}
5°) Open a terminal and:
cd /path/to/my/android/project/app/src/main/java
javac com/so/test/Test.java
javah com.so.test.Test
This creates the "com_so_test_Test.h" file.
cd /path/to/my/android/project
mkdir jni
mv app/src/main/java/com_so_test_Test.h jni
touch jni/com_so_test_Test.cpp
6°) Add the following code in "com_so_test_Test.cpp" file:
#include <jni.h>
#include <stdio.h>
#include "com_so_test_Test.h"
#include "Test.hpp"
JNIEXPORT jstring JNICALL Java_com_so_test_Test_getMessage(JNIEnv* env, jobject ob)
{
return env->NewStringUTF(Test::getTest().c_str());
}
7°) Copy "Test.h" and "libTest.so" files created on steps 1 & 2 into "jni" folder
8°) Create an "Android.mk" file in the "jni" folder containing:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hellondk
LOCAL_SRC_FILES := com_so_test_Test.cpp
include $(BUILD_SHARED_LIBRARY)
9°) Create an "Application.mk" file in the "jni" folder containing:
APP_STL := stlport_static
10°) Back in the terminal, run:
/path/to/your/ndk/ndk-build
And that's the step where I'm stuck. I need to reference the libTest.so file in the Android.mk, but all the solutions I tried did not work. Any idea?
EDIT: here is the error I get:
[arm64-v8a] Compile++ : hellondk <= com_so_test_Test.cpp
[arm64-v8a] SharedLibrary : libhellondk.so
./obj/local/arm64-v8a/objs/hellondk/com_so_test_Test.o: In function `Java_com_so_test_Test_getMessage':
/Users/timsandra/Desktop/CppTest/jni/com_so_test_Test.cpp:8: undefined reference to `Test::getTest()'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [obj/local/arm64-v8a/libhellondk.so] Error 1
I am trying to compile a device driver for my target platform which is Snapdragon msm8974. I added some more code to an already tested module; and added more header files. One of the header files was not in my include directory, so I searched in my environment and found a number of options so I chose
~/android/android-ndk-r10d/platforms/android-19/arch-arm/usr/include/stdint.h
But I keep getting the following error, and do not know how to go about fixing it. Any advice on what I can do differently is greatly appreciated. Here is the error:
include/linux/stdint.h:32:24: fatal error: sys/_types.h: No such file or directory
compilation terminated.
Here is all my include statements in the file:
#include <inttypes.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <stdlib.h>
Trying to load live555 library but having following error when I do ndk-build
Compile++ thumb : live555 <= Locale.cpp
In file included from jni/live555/Locale.cpp:22:0:
/Volumes/Projects/Ayaz_Projects/streamer/./jni/live555/include/Locale.hh:47:123: fatal error: xlocale.h: No such file or directory
compilation terminated.
make: *** [obj/local/armeabi/objs/live555/Locale.o] Error 1
xlocale.h is nowhere in the live555 code
What should I do?
The include file has the following:
#ifndef LOCALE_NOT_USED
#include <locale.h>
#ifndef XLOCALE_NOT_USED
#include <xlocale.h> // because, on some systems, <locale.h> doesn't include <xlocale.h>; this makes sure that we get both
#endif
#endif
So you should be able to add -DXLOCALE_NOT_USED to your Android.mk to avoid this.
I got here seearching for xlocale.h not found (unrelated to android development). My solution was https://serverfault.com/a/791822/394721
I'm encountering an issue with linking C libraries in my Android project using the Android NDK r8b.
I built with the toolchain for ARM the cURL library (no SSL) and it provided me a libcurl.a file and a libcurl.so.4.2.0 one.
I also created a C file to provide functions to my Java code and to use the cURL library.
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= libcurl
LOCAL_SRC_FILES := libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := curljni
LOCAL_SRC_FILES := curljni.c
LOCAL_STATIC_LIBRARIES := libcurl
include $(BUILD_SHARED_LIBRARY)
and now my C file
#include <string.h>
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
jstring Java_test_curljni_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz)
{
CURL *curl;
CURLcode
......
}
When I try to build with the ndk-build command from my project folder, here's the output error :
Compile thumb : curljni <= curljni.c
jni/curljni.c: In function 'Java_test_curljni_MainActivity_stringFromJNI':
jni/curljni.c:8:3: error: unknown type name 'CURL'
jni/curljni.c:9:3: error: unknown type name 'CURLcode'
jni/curljni.c:11:8: warning: assignment makes pointer from integer without a cast [enabled by default]
jni/curljni.c:13:28: error: 'CURLOPT_URL' undeclared (first use in this function)
jni/curljni.c:13:28: note: each undeclared identifier is reported only once for each function it appears in
/cygdrive/c/android-ndk-r8b/build/core/build-binary.mk:252: recipe for target `obj/local/armeabi/objs/curljni/curljni.o' failed
make: *** [obj/local/armeabi/objs/curljni/curljni.o] Error 1
I've tried many things within the Android.mk file, nothing successful. Using a PREBUILT_SHARED_LIBRARY doesn't help because it requires a .so file only and changing the extension from .so.4.2.0 to .so just tells me that the format is not supported when building ...
One thing I'm not sure about if whether I have to include the headers in my C file, but when I do it, it ofcourse don't find them.
As a note, when I build with only the curl library declared in my Android.mk file (the shared library with the C file is ommitted) then nothing is created in the libs folder !
Thanks in advance for your help !
EDIT ::::
Actually it did work mbrenon (I've tried it millions time and now it works, no idea what's different), but now I have
c:/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../. ./arm-linux-androideabi/bin/ld.exe: cannot find ./obj/local/armeabi/libcurl.a: Permission denied
I'm using Cygwin, could that be why I encounter permission issues ?
I manage to get around it when the .so and the .a are created, returning the permission error, chmod on it and running the ndk-build again, but that seems a bit rough !
Plus now none of my curl functions can be reached ("undefined reference to (function)").
$ ../../../ndk-build
SharedLibrary : libcurljni.so
./obj/local/armeabi/objs/curljni/curljni.o: In function `Java_test_curljni_MainActivity_stringFromJNI':
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:12: undefined reference to `curl_easy_init'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:14: undefined reference to `curl_easy_setopt'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:15: undefined reference to `curl_easy_perform'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:17: undefined reference to `curl_easy_cleanup'
collect2: ld returned 1 exit status
/cygdrive/c/android-ndk-r8b/build/core/build-binary.mk:378: recipe for target `obj/local/armeabi/libcurljni.so' failed
make: *** [obj/local/armeabi/libcurljni.so] Error 1
and my curljni.c is the following
jstring Java_test_curljni_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz)
{
CURL *curl;
CURLcode res;
char buffer[10];
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "yahoo.com");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(res == 0)
return (*env)->NewStringUTF(env, "0 response");
else
sprintf(buffer,"code: %i",res);
return (*env)->NewStringUTF(env, buffer);
}
else {
return (*env)->NewStringUTF(env, "no curl");
}
}
I made sure every needed function is declared in the curl.h
Yes, you do have to include the Curl headers in your C file. To allow ndk-build to find these header files at link time, you'll have to add their path using LOCAL_EXPORT_C_INCLUDES:
include $(CLEAR_VARS)
LOCAL_MODULE:= libcurl
LOCAL_SRC_FILES := libcurl.a
LOCAL_EXPORT_C_INCLUDES := /* put the path to the Curl headers here */
include $(PREBUILT_STATIC_LIBRARY)
This will automatically add the path to the headers in all the targets requiring libcurl, and it should build and link.
I am trying to call a simple connection function from native C code using the NDK and JNI. The following is my code:
C code - returns a value
freerdp_ext_connect(const char *host, const char *username,
const char *pass, const char *domain,
int width, int height){}
Java code:
#include <jni.h>
#include <stdio.h>
#include <freerdp/freerdp.h>
jstring Java_com_example_freerdpandroid_FreeRDPActivity_test(JNIEnv* env, jobject javaThis)
{
freerdp_ext_connect("10.123.123.12", "admin", "dsadsad", "", 600, 800);
return (*env)->NewStringUTF(env, "dsfsdf");
}
When trying to compile with cygwin it's giving me this error:
./obj/local/armeabi/objs/freerdp/freerdp.o: In function `Java_com_example_freerdpandroid_FreeRDPActivity_test':
C:\Users\stefan.scerri\workspace\freerdp/jni/freerdp.c:11: undefined reference to `freerdp_ext_connect'
collect2: ld returned 1 exit status
/cygdrive/c/android-ndk/android-ndk/build/core/build-binary.mk:378: recipe for target `obj/local/armeabi/libfreerdp.so' failed
make: *** [obj/local/armeabi/libfreerdp.so] Error 1
Any idea why this is so? I believe it is because of the return value of the C function, however I'm not sure, can someone kindly confirm. Thanks in advance.
Is the freerdp_ext_connect in a compiled library, by any chance? If so, are you linking to that library when you build your NDK project? To link with a library, place the following into Android.mk:
LOCAL_LDLIBS := -lfoo
And the linker will link against libfoo.a or libfoo.so, whichever is available.
If freerdp_ext_connect is in a source file - are you compiling that source file? The source file must be listed under LOCAL_SRC_FILES in Android.mk.