1

i am using NDK to join java with C++ this my code :

MainActivity.java

public class MainActivity extends Activity {

/*Don't forget to load the library!!*/
static {
    System.loadLibrary("NDK1");
}

public native String exec(String cmd);

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
 # Here we give our module name and source file(s)
LOCAL_MODULE    := NDK1
LOCAL_SRC_FILES := NDK1.cpp
include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI := armeabi armeabi-v7a
APP_STL := gnustl_static

NDK1.cpp

#include <string>
#include <iostream>
#include <stdio.h>
 #include <jni.h>

   std::string exec(char* cmd) {
  FILE* pipe = popen(cmd, "r");
  if (!pipe) return "ERROR";
 char buffer[128];
 std::string result = "";
 while(!feof(pipe)) {
     if(fgets(buffer, 128, pipe) != NULL)
     result += buffer;
 } 
 pclose(pipe);
 return result;
}

  jstring Java_com_example_ndk1_MainActivity_exec(JNIEnv* env, jobject javaThis , jstring   cmd) {
char * res;

    res = env->GetStringUTFChars(cmd ) ;

std::string result = exec(res);
  return env->NewStringUTF(result);
 }

but have this error !!!

    $ /cygdrive/c/android-ndk-r4/ndk-build
   make: Warning: File `/cygdrive/c/android-ndk-r4/build/core/import-locals.mk' has    modification time 140680622 s in the future
 Compile++ thumb  : NDK1 <= NDK1.cpp
 jni/NDK1.cpp: In function '_jstring* Java_com_example_ndk1_MainActivity_exec(JNIEnv*,   jobject, jstring)':
 jni/NDK1.cpp:22:39: error: no matching function for call to   '_JNIEnv::GetStringUTFChars(_jstring*&)'
 jni/NDK1.cpp:22:39: note: candidate is:
 C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:860:17: note: char   const* _JNIEnv::GetStringUTFChars(jstring, jboolean*)
 C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:860:17: note:     candidate expects 2 arguments, 1 provided
 jni/NDK1.cpp:25:36: error: no matching function for call to  '_JNIEnv::NewStringUTF(std::string&)'
 jni/NDK1.cpp:25:36: note: candidate is:
 C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:854:13: note: _jstring*  _JNIEnv::NewStringUTF(char const*)
 C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:854:13: note:   no known  conversion for argument 1 from 'std::string {aka std::basic_string<char>}' to 'char const*'
 /cygdrive/c/android-ndk-r4/build/core/build-binary.mk:269: recipe for target  `obj/local/armeabi/objs/NDK1/NDK1.o' failed
 make: *** [obj/local/armeabi/objs/NDK1/NDK1.o] Error 1
Anirudh Sharma
  • 7,968
  • 13
  • 40
  • 42
Hana90
  • 943
  • 5
  • 17
  • 37

2 Answers2

4

after many tries to catch the problem this is the solution without causing any error :

jstring Java_com_example_ndk1_MainActivity_exec(JNIEnv* env, jobject javaThis , jstring cmd) {
const char * res;

    jboolean isCopy;
    res = env->GetStringUTFChars(cmd, &isCopy);

    if (isCopy == JNI_TRUE) {
        (env)->ReleaseStringUTFChars(cmd, res);
    }

std::string result = exec(res);
return (env)->NewStringUTF((const char* )result.c_str());
 }
Hana90
  • 943
  • 5
  • 17
  • 37
  • You should **always** call `ReleaseStringUTFChars` if `GetStringUTFChars` succeeded. Even if isCopy!=JNI_TRUE. Also there is no need cast result of `c_str()` to `const char*` because it is already const char*. – Mārtiņš Možeiko Mar 03 '13 at 02:59
  • thanks i am using c++ extensions and removing env* parameter from NewStringUTF worked for me – duckduckgo Jul 25 '13 at 05:05
  • in my cpp file it worked if i moved env->ReleaseStringUTFChars(cmd, res); at the end. – hB0 Nov 04 '13 at 22:50
2

[edited to make the answer more generic - there are several errors in the code]

For every error of the type no matching function for call to, look up the definition of the function in the JNI reference

Make sure that you are:

  • Passing all required parameters
  • The parameters are of the required type

For example, the call to GetStringUTFChars is missing parameters and the call to NewStringUTF doesn't take a std::string as parameter. It wants a const char *.

For the NewStringUTF, try:

return (*env)->NewStringUTF(env, (const char*)result.c_str());

This JNI tutorial is also nice: http://www.steveolyo.com/JNI/JNI.html

Christian Garbin
  • 2,512
  • 1
  • 23
  • 31
  • Still have error jni/NDK1.cpp: In function '_jstring* Java_com_example_ndk1_MainActivity_exec(JNIEnv*, jobject, jstring)': jni/NDK1.cpp:22:39: error: no matching function for call to '_JNIEnv::GetStringUTFChars(_jstring*&)' jni/NDK1.cpp:22:39: note: candidate is: C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:860:17: note: char const* _JNIEnv::GetStringUTFChars(jstring, jboolean*) – Hana90 Mar 02 '13 at 17:02
  • C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:860:17: note: candidate expects 2 arguments, 1 provided /cygdrive/c/android-ndk-r4/build/core/build-binary.mk:269: recipe for target `obj/local/armeabi/objs/NDK1/NDK1.o' failed make: *** [obj/local/armeabi/objs/NDK1/NDK1.o] Error 1 Chat Conversation End – Hana90 Mar 02 '13 at 17:03
  • I didn't notice the missing `env` needed for the JNI function calls. See my edited response and the links I added. – Christian Garbin Mar 02 '13 at 17:14
  • STILL error jni/NDK1.cpp: In function '_jstring* Java_com_example_ndk1_MainActivity_exec(JNIEnv*, jobject, jstring)': jni/NDK1.cpp:22:39: error: no matching function for call to '_JNIEnv::GetStringUTFChars(_jstring*&)' jni/NDK1.cpp:22:39: note: candidate is: C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:860:17: note: char const* _JNIEnv::GetStringUTFChars(jstring, jboolean*) C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:860:17: note: candidate expects 2 arguments, 1 provided – Hana90 Mar 02 '13 at 17:30
  • jni/NDK1.cpp:25:49: error: no matching function for call to '_JNIEnv::NewStringUTF(JNIEnv*&, char const*)' jni/NDK1.cpp:25:49: note: candidate is: C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:854:13: note: _jstring* _JNIEnv::NewStringUTF(char const*) C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:854:13: note: candidate expects 1 argument, 2 provided /cygdrive/c/android-ndk-r4/build/core/build-binary.mk:269: recipe for target `obj/local/armeabi/objs/NDK1/NDK1.o' failed make: *** [obj/local/armeabi/objs/NDK1/NDK1.o] Error 1 – Hana90 Mar 02 '13 at 17:31
  • See edited example again. This time I made it look like the code we use in a project (unfortunately I don't have the NDK on the laptop I'm using now to experiment on my own). I added the cast to `const char*` even though that's what `c_str()` signature says it should return. Other than that I won't be able to help you much. Except for the `c_str()` part, the code is now what works for me. Also notice that the call to `NewStringUTF` has been changed to `(*env)->...` – Christian Garbin Mar 02 '13 at 17:45
  • still error jni/NDK1.cpp: In function '_jstring* Java_com_example_ndk1_MainActivity_exec(JNIEnv*, jobject, jstring)': jni/NDK1.cpp:22:39: error: no matching function for call to '_JNIEnv::GetStringUTFChars(_jstring*&)' jni/NDK1.cpp:22:39: note: candidate is: C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:860:17: note: char const* _JNIEnv::GetStringUTFChars(jstring, jboolean*) – Hana90 Mar 02 '13 at 18:08
  • C:/android-ndk-r4/platforms/android-14/arch-arm/usr/include/jni.h:860:17: note: candidate expects 2 arguments, 1 provided jni/NDK1.cpp:25:15: error: base operand of '->' has non-pointer type 'JNIEnv {aka _JNIEnv}' /cygdrive/c/android-ndk-r4/build/core/build-binary.mk:269: recipe for target `obj/local/armeabi/objs/NDK1/NDK1.o' failed make: *** [obj/local/armeabi/objs/NDK1/NDK1.o] Error 1 – Hana90 Mar 02 '13 at 18:08
  • Kicking myself for not having read this more carefully: `no matching function for call to '_JNIEnv::GetStringUTFChars`. You error is in the call to `GetStringUTFChars`. You are missing parameters for that function. See the definition of that function in http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html and read http://stackoverflow.com/questions/5859673/should-you-call-releasestringutfchars-if-getstringutfchars-returned-a-copy – Christian Garbin Mar 02 '13 at 18:18
  • i rewrite code as below: 'char * res; jboolean isCopy; res = env->GetStringUTFChars(cmd, &isCopy); if (isCopy == JNI_TRUE) { env->ReleaseStringUTFChars(cmd, res); } std::string result = exec(res); return (*env)->NewStringUTF(env, (const char)result.c_str());' – Hana90 Mar 02 '13 at 19:53
  • but still there are errors: Java_com_example_ndk1_MainActivity_exec(JNIEnv*, jobject, jstring)': jni/NDK1.cpp:26:47: error: invalid conversion from 'char const*' to 'char*' [-fpermissive] jni/NDK1.cpp:33:15: error: base operand of '->' has non-pointer type 'JNIEnv {aka _JNIEnv}' jni/NDK1.cpp:33:60: error: cast from 'char const*' to 'char const' loses precision [-fpermissive] – Hana90 Mar 02 '13 at 19:55
  • /cygdrive/c/android-ndk-r4/build/core/build-binary.mk:269: recipe for target `obj/local/armeabi/objs/NDK1/NDK1.o' failed make: *** [obj/local/armeabi/objs/NDK1/NDK1.o] Error 1 – Hana90 Mar 02 '13 at 19:55
  • You have to help yourself a bit. Read the error message and try to figure what is about. Sometimes the compiler can be obscure, but most of the time you just need to read it with more attention. For example, the compiler just told you `cast from 'char const*' to 'char const'` because your cast is wrong `(const char)` (where is the `*` from my sample)? Sorry, but I can't help you anymore if you aren't trying to read the compiler error messages and check the available documentation. If you need something else, please be more specific about what you tried and what you think the error may be. – Christian Garbin Mar 02 '13 at 20:00
  • ok , i remove it from my previous comment of code ! return (*env)->NewStringUTF(env, (const char)result.c_str()); – Hana90 Mar 02 '13 at 20:04