this code invoked Linux command by using C++ code, but how to convert it to use it as lib via NDK? i see examples that use just .C files, and the variables used by Jni that different than C++ variable.
this c++ code that i need to convert it to use it then with NDK
#include <string>
#include <iostream>
#include <stdio.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;
}
is this suitable to do?
in 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)
suppose my native method is exec(char* cmd), for NDK1.cpp
#include <string>
#include <iostream>
#include <stdio.h>
#include <jni.h>
jstring Java_com_mindtherobot_samples_ndkfoo_MainActivity_exec(JNIEnv* env, jobject javaThis , Jchar* cmd) {
......... same code above
return result;
}
how to arrange these files to have a correct solution ?
You still need the MainActivity java code with the native method declaration. I don't know if you didn't post that or you forgot to implement it. it should be something like this:
public class MainActivity extends Activity
{
/*Don't forget to load the library!!*/
static {
System.loadLibrary("NDK1");
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// your initialization here...
}
public native String exec(String cmd);
}
In addition, as g-makulik pointed in a comment, you are returning a c++ string in your native code, but you should return a Java string. The NDK1.cpp file should be something similar to this:
#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_mindtherobot_samples_ndkfoo_MainActivity_exec(JNIEnv* env, jobject javaThis , Jchar* cmd) {
std::string result = exec(cmd);
return (*env)->NewStringUTF(env, result);
}
Finally, you should run the ndk-build script to generate the shared library for your code. Be sure to put the NDK1.cpp file in the same directory as the Android.mk file, in the jni folder (assuming you don't want to change your Android.mk file to look for the sources somewhere else). Suposing you are using linux (I don't know how it works for Windows), you should open a terminal where you have your Android.mk. There you must run the command 'ndk-build'. If everything is fine you won't get any errors, and the .so file will be copied in the libs file of your project.
UPDATE: Maybe you need to add the stl library to use the string class. You can try to add an Application.mk file in the same directory as the Android.mk with this content:
APP_ABI := armeabi armeabi-v7a
APP_STL := gnustl_static
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With