how can i handle more string from native-lib.cpp class
i tried this
Java:
....
public List<String> getFooAsList(){
return new ArrayList(this.getData());
}
private native String[] getData();
JNI
#include <jni.h>
JNIEXPORT jobjectArray JNICALL
como_foo_bar_getData
(JNIEnv *env, jobject jobj){
jobjectArray ret;
int i;
char *data[5]= {"Hello from C++", "Hello from B++", "Hello from A++", "Hello from D++";
ret= (jobjectArray)env->NewObjectArray(5,env->FindClass("java/lang/String"),env->NewStringUTF(""));
for(i=0;i<5;i++) env->SetObjectArrayElement(ret,i,env->NewStringUTF(data[i]));
return(ret);
}
nativ-liv.cpp
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring
JNICALL
Java_in_gov_civilsupplieskerala_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
std::string hello3 = "Hello from A++";
std::string hello2 = "Hello from B++";
std::string hello1 = "Hello from D++";
return env->NewStringUTF(hello.c_str());
}
It only take first value,how can i take all string value from native-lib.cpp class
Related
I am using NDK in my android app . There was no problem . Here is the code for c++ file
#include <jni.h>
#include <string>
#include <stdio.h>
extern "C" JNIEXPORT jstring JNICALL
Java_com_examples_core_MyApplication_getKeyJNI(
JNIEnv *env,
jobject /* this */) {
std::string secret_key = "mysecret";
return env->NewStringUTF(secret_key.c_str());
}
Edit
Here is my approach
my native-lib.cpp
#include <jni.h>
#include <string>
#include <unistd.h> // for getcwd()
#include <iostream>
#include <stdio.h>
#include "constants.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_examples_core_MyApplication_getKeyJNI(
JNIEnv *env,
jobject /* this */) {
std::string secret_key = secret_key;
return env->NewStringUTF(secret_key.c_str());
}
my constants.h
#pragma once
#include <string>
extern const std::string secret_key; // declaration
my constants.cpp
#include "constants.h"
const std::string secret_key = "mysecret"; // definition
When I compile I get the following error
native-lib.cpp:13: undefined reference to `secret_key'
You don't want to put the definition in a header file, as that could lead to multiple definitions of the same variable.
But you could do something like this:
constants.h
#pragma once
#include <string>
extern const std::string secret_key; // declaration
constants.cpp
#include "constants.h"
const std::string secret_key = "mysecret"; // definition
main.cpp
#include <iostream>
#include "constants.h"
int main()
{
std::cout << secret_key; // usage
}
I am doing development in Android using C/C++. I have a C++ function, that needs to be called from a C file. Here is what I am doing right now, but I get the error
undefined reference to __check_expiry
The C++ function is defined in "a.h" and implemented in "a.cpp". I am including "a.h" in"b.c" file and calling the method "__check_expiry" from "b.c" file.
a.h :
#ifdef __cplusplus
extern "C" {
#endif
static int __check_expiry(void);
#ifdef __cplusplus
}
#endif
a.cpp:
extern "C" {
static int __check_expiry() {
vz::lock_guard<std::mutex> guard(mutex_check, lock_hooker_check);
JNIEnv *env = NULL;
static bool __is_attached_1 = false;
if ((env = __getEnv(&__is_attached_1)) == NULL) {
//log_info("getEnv fail\r\n");
}
assert(!__is_attached_1);
int obj = env->CallStaticIntMethod((jclass) g_class, g_methodID);
log_info("Returned value from JAVA %d", obj);
__releaseEnv(__is_attached_1);
guard.~lock_guard();
return obj;
}
}
b.c:
#ifdef __cplusplus
extern "C" {
#endif
#include "a.h"
#ifdef __cplusplus
}
#endif
static int tunnel_to()
{
int value = __check_expiry();
}
Static functions are not exported. Remove the static qualifier.
(Unrelated: as long as you #include "a.h" from a.cpp, you don't need the extern "C" in your source file.)
I have already tried NDK simple examples such as displaying data from a native code to android's java code such as this:
#include <jni.h>
extern "C" {
JNIEXPORT jstring JNICALL
Java_com_example_JNIActivity_stringFromJNI( JNIEnv* env,
jobject thiz )
{
return env->NewStringUTF("I'm C++! What the hell am I doing here in android?!");
}
}
However, I want an application wherein user will have to enter data from a textfield and have this data be pass from it's java code to the native code where calculations will be done. How will I do this?
In your Java native method, include a formal String argument that accepts the textfield value.
In C/C++, access the characters from the jstring with JNI methods like these:
jsize GetStringLength(JNIEnv *env, jstring string);
const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy);
const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy);
When you're done with the characters, be sure to release them.
void ReleaseStringChars(JNIEnv *env, jstring string, const jchar *chars);
void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf);
See the documentation for these methods in the Java Native Interface Specification.
I'm working in an Android project with c++ files (NDK) but i have faced a problem
native method not found , when i add the
extern "C" {
} i got new problem which is declaration of c function '..' conflicts with .h previous declaration
here is my code
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_marwen_parojet_ocr_2_PostPhot */
#ifndef _Included_com_marwen_parojet_ocr_2_PostPhot
#define _Included_com_marwen_parojet_ocr_2_PostPhot
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_marwen_parojet_ocr_2_PostPhot
* Method: Traiter
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_marwen_parojet_1ocr_12_PostPhot_Traiter
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
this traitement_jni.h
and the .cpp file is
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv/cv.h>
#include "opencv2/ml/ml.hpp"
#include <android/log.h>
#include <jni.h>
#include "traitement_jni.h"
#include <stdlib.h>
extern "C" {
JNIEXPORT void JNICALL Java_com_marwen_parojet_1ocr_12_PostPhot_Traiter(JNIEnv* env, jobject,jstring path){
...
}
}
It seems you are passing a jclass in the declaration but a jobject in the definition. If these two types aren't aliases for the same type, this doensn't work: you cannot overload extern "C" functions.
header file:
extern "C" {
JNIEXPORT void JNICALL Java_com_marwen_parojet_1ocr_12_PostPhot_Traiter(
JNIEnv *,
jclass, // <---- here
jstring);
}
source file:
...
extern "C" {
JNIEXPORT void JNICALL Java_com_marwen_parojet_1ocr_12_PostPhot_Traiter(
JNIEnv* env,
jobject, // <---- here
jstring path){
...
}
}
android project:
i HAve c. file :
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <com_jp_algi_Corelib.h>
/* Header for class com_jp_algi_Corelib */
#ifdef __cplusplus
#define EXTCFUNC extern "C"
#elseif
#define EXTCFUNC extern
#endif
JNIEXPORT jfloatArray JNICALL Java_com_jp_algi_Corelib_vector
(JNIEnv * env, jobject clazz, jfloatArray input){
jfloatArray result;
}
jfloat* flt1 = env->GetFloatArrayElements(input,0)
;insiperd by : Eiegen android in the stackflow.
and there is some error:
C:/AA/FileBroswerActivity/jni/com_jp_algi_Corelib.c:23: error: 'env' undeclared here (not in a function)
C:/AA/FileBroswerActivity/jni/com_jp_algi_Corelib.c:23: error: 'input' undeclared here (not in a function)
/cygdrive/c/android-ndk-r5c/build/core/build-binary.mk:217: recipe for target `/cygdrive/c/AA/FileBroswerActivity/obj/local/armeabi/objs/com_jp_algi_Corelib/com_jp_algi_Corelib.o' failed
make: *** [/cygdrive/c/AA/FileBroswerActivity/obj/local/armeabi/objs/com_jp_algi_Corelib/com_jp_algi_Corelib.o] Error 1
16:52:03 Build Finished (took 672ms)
Your post is really unclear but your files should looks like this
.h file:
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
jfloatArray JNICALL Java_com_jp_algi_Corelib_vector(JNIEnv * env, jobject clazz, jfloatArray input);
#ifdef __cplusplus
}
#endif
.cpp file:
#include "yourheader.h"
#ifdef __cplusplus
extern "C" {
#endif
jfloatArray JNICALL Java_com_jp_algi_Corelib_vector(JNIEnv * env, jobject clazz, jfloatArray input)
{
jfloat* flt1 = env->GetFloatArrayElements(input,0);
}
#ifdef __cplusplus
}
#endif
Edit(after your edit):
jfloat* flt1 = env->GetFloatArrayElements(input,0);
is outside function body