JNIEXPORT and JNICALL in Android NDK - android

While working with some sources written in C++ I found those macro:
JNIEXPORT return_type JNICALL function_name(...) {
However, Android NDK samples don't use them. I read some docs from Oracle, but I'm still confused.
Do I necessarily have to use them while working with Android NDK?
One of the reasons for asking - those macro break syntax highlighting in eclipse CDT :)

Basically is a windows issue, if you have a look to the file jni_md_win32.h that comes with oracle Java jdk this is the macro definition:
/*
* #(#)jni_md.h 1.14 03/12/19
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
typedef long jint;
typedef __int64 jlong;
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */
In the header jni_md_linux.h those macros are empty. So I guess that as long you don't want your native code to be executed in windows with oracle JVM you can remove those macros.

Check that the include path of the platform you desire from the Android NDK has been added to your project's C\C++ includes. This can be done as follows:
Open the project properties
Expand C/C++ General
Click Paths and Symbols
In the Includes section Add the path to the includes folder of the desired platform of the NDK (e.g. ${ANDROID_NDK_HOME}\platforms\android-9\arch-arm\usr\include )

Related

Why is this c++ namespace giving me grief?

First off, my app has a file named Android.hpp. This is part of the tmxlite library. Compiling tmxlite on windows works fine. However, when I move the code to android studio and compile it (with the NDK), I get an error.
Android.hpp:
/*********************************************************************
Matt Marchant 2016
http://trederia.blogspot.com
tmxlite - Zlib license.
This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but
is not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any
source distribution.
*********************************************************************/
#ifndef ANDROID_INC_HPP_
#define ANDROID_INC_HPP_
#ifdef __ANDROID__
#include <string>
#include <sstream>
#include <cstdlib>
namespace std
{
template <typename T>
std::string to_string(T value)
{
std::ostringstream os;
os << value;
return os.str();
}
}
#define STOI(str) std::strtol(str.c_str(), 0, 10)
#else
#define STOI(str) std::stoi(str)
#endif // __ANDROID__
#endif // ANDROID_INC_HPP_
The error:
In file included from E:\max\android_libs\tmxliteOG\tmxlite\src\FreeFuncs.cpp:28:
In file included from E:\max\android_libs\tmxliteOG\tmxlite\include\tmxlite\FreeFuncs.hpp:54:
E:\max\android_libs\tmxliteOG\tmxlite\include\tmxlite\detail\Android.hpp:37:11: error: expected '{'
Why is this happening? I was under the impression that this was how namespaces were supposed to be declared and I don't see what is wrong with it. I mean, I didn't even write the code :-).
help is greatly appreciated.

Linker can't find function

Im trying to build an Ubuntu Touch tree, based on an Aosp tree I already correctly built.
It fails with this error
CAPEWrapper.cpp:16: error: undefined reference to '__xlog_buf_printf'
this is the header that file includes
#include "CAPEWrapper.h"
which on cascade includes
#include <cutils/xlog.h>
which in turn defines
#if defined(__cplusplus)
extern "C" {
#endif
int __xlog_buf_printf(int bufid, const struct xlog_record *rec, ...);
#if defined(__cplusplus)
}
#endif
I suspect that my g++ doesn't set __cplusplus macro. Could it be a realistic scenario with this kind of error? If this could be the problem, should I need to specify a standard implementation with "stdc=something" to solve it?
Any other idea is welcome.
Make sure that your project is linking libcutils, and that it's linking it in the correct order (i.e. that -lcutils appears in the linker command line after any module that depends on it).
In the end, I found that the modules was listed inside a macro called LOCAL_WHOLE_STATIC_LIBRARIES, that in Android environment passes its content to the --whole-archive flag of GCC linker.

Android NDK compiling C++ code gets a Type 'errno_t' could not be resolved

I'm compiling C++ code written primarily for Mac OS, using the Android NDK and I get the following error:
- Type 'errno_t' could not be resolved
In Xcode this type is defined on OSX 10.0/usr/include/sys/_types/_errno_t.h as this:
#ifndef _ERRNO_T
#define _ERRNO_T
typedef int errno_t;
#endif /* _ERRNO_T */
Any suggestions on how to convert this to the NDK, or add compiler flags to make this compile, or where to even get the source code to define this type in my source code itself?
Thanks.
See this answer for information on errno_t.
errno_t is not a part of the C standard, and bionic doesn't support it.
The fix is simply to change all the errno_ts to be ints.

How does Android source building #ifdefs work in compilation

I'm familiar with Android kernel programming but I'm a newbie at building the Android source. I'm wondering how to enable the #ifdefs in android source building. Are there any defconfig file in android source like in android kernel to choose what we want to compile in the compilation?.. How can i enable the codings defined with #ifdef to get compile during the Android source compilation?
Ex:
#ifdef USE_ION
int alloc_map_ion_memory(OMX_U32 buffer_size,
OMX_U32 alignment, struct ion_allocation_data *alloc_data,
struct ion_fd_data *fd_data,int flag);
void free_ion_memory(struct vdec_ion *buf_ion_info);
#else
bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
OMX_U32 alignment);
#endif
I want to make sure the ion part is being compiled not the pmem part.
Try add the line:
#error "USE_ION"
after #ifdef USE_ION
Build again, if the build failed, USE_ION is defined.

How to create dll using android

I am new to Android application development.I want develop a dll using android. Is it possible to develop and integrate to android app. Please tell me the solution. If it is possible please tell me the solution one by one.
As for me I once made a note for myself about NDK. Here it is:
Required applicaitions:
1. Eclipse
2. CDT+Sequoyah plug-ins
3. Android ADT
4. Android NDK
Configuration:
1. Install Eclipse, ADT, CDT and Sequoyah plug-ins
2. In the Eclipse -> Window -> Preferences -> Android -> Native Development put NDK location
Steps:
1. Create new Android Project
2. Create Java class for working with native libraries (NativeLibrary.java)
3. In the class NativeLibrary.java define interface for native methods
4. Right click on Project -> Android Tools -> Add Native Support. Define name of the library.
5. Build the project
6. Go to PROJECT_HOME/bin
7. Create C header file with the command javah -jni <packagename>.NativeLibrary
8. Move this file to PROJECT_HOME/jni folder
9. Implement methods from the header file in the generated cpp file. Do not forget to include the moved header in this file.
10. In java classes create new object of NativeLibrary class and call its methods.
11. Build project.
UPDATE: Step by step without plugins
Required applications - this is what you need to develop native applications. In my case I use Eclipse + Android ADT plugin + Android CDT plugin + Sequoyah plugin. You can install them using Eclipse - > Install new software
Then you should download Android NDK. Also you should export PATH to it.
For the configuration: you should define only path to your NDK in Eclipse -> Window -> Preferences -> Android -> Native Development
You are not obliged to use these plugins but it is easier to develop with them. However, Sequoyah contains errors (or it's sometimes not properly configured for my computer)
After that you can create new Android project. Then you can create java class that defines native methods. In my case this is NativeLibrary.java. Here it is:
package com.testpack.nativetest;
public class NativeLibrary {
public native static int add(int a, int b);
static {
System.loadLibrary("nativ");
}
}
After that build your Android project. After that go to your bin/classes (I don't know but before it was just bin directory) directory:
cd ~/programming/android/workspace/NativeTest/bin/classes
And run the following command:
javah -jni com.testpack.nativetest.NativeLibrary
This command should produce com_testpack_nativetest_NativeLibrary.h header in your bin/classes directory. It should look like:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_testpack_nativetest_NativeLibrary */
#ifndef _Included_com_testpack_nativetest_NativeLibrary
#define _Included_com_testpack_nativetest_NativeLibrary
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_testpack_nativetest_NativeLibrary
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_testpack_nativetest_NativeLibrary_add
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
Create jni directory in your project and Run the following command. It will move this header to jni directory.
mv com_testpack_nativetest_NativeLibrary.h ../../jni
After that in jni directory create .c file. In my case it is nativ.c, copy the definition of the function from .h file and generate code:
#include "com_testpack_nativetest_NativeLibrary.h"
JNIEXPORT jint JNICALL Java_com_testpack_nativetest_NativeLibrary_add
(JNIEnv *env, jclass obj, jint a, jint b) {
return a+b;
}
Then in jni directory you should create a make file Android.mk Here it is. Simply change the source (nativ.c) and the name of your library (nativ).
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := nativ
LOCAL_SRC_FILES := nativ.c
include $(BUILD_SHARED_LIBRARY)
Go to the PROJECT_HOME directory. In my case this is
cd ~/programming/android/workspace/NativeTest
and run ndk-build. That's all. After that you can test it in your activity:
package com.testpack.nativetest;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class NativeTestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d("TEST:", "Result 5+4=" + NativeLibrary.add(5, 4));
}
}
With plugins it is a bit easier to develop. But I think you should test it by yourself how to do this.
You can check out the Android NDK, here http://developer.android.com/sdk/ndk/index.html.
The NDK can be used to create linux equvalent .so, of the windows .dll files.

Categories

Resources