英文:
Pass Java double array to C++ in Android Studio project
问题
C++代码:
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_covid19_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Test string from C to java";
return env->NewStringUTF(hello.c_str());
}
extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_example_covid19_MainActivity_getDouble(JNIEnv *env, jobject /* this */) {
double initialArray[] = {0, 4, 5, 6, 7};
jsize length = sizeof(initialArray) / sizeof(initialArray[0]);
jclass doubleClass = env->FindClass("java/lang/Double");
jobjectArray doubleArray = env->NewObjectArray(length, doubleClass, NULL);
for (int i = 0; i < length; i++) {
jdouble value = initialArray[i];
jobject doubleObject = env->NewObject(doubleClass, env->GetMethodID(doubleClass, "<init>", "(D)V"), value);
env->SetObjectArrayElement(doubleArray, i, doubleObject);
}
return doubleArray;
}
Java代码:
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
public double[] getDouble(){
double[] j = {0, 4, 5, 6, 7};
return j;
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
public native double[] getDouble();
}
英文:
I'm working in an Android Studio project in Java that requires C++ for some signal processing functions. I need to be able to pass an array type Double from Java to C++. I've tried to lean heavily on examples, such as this (https://stackoverflow.com/questions/21065390/get-java-array-from-c-via-jni?noredirect=1&lq=1), with the MainActivity.java file already linked as a jobject in my native-lib.cpp file, I think I am making this too complicated. Is there is an easier way to pass variables back and forth? (In my very rudimentary example below, I created a method called 'getDouble' just to test this out)
C++ code:
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_covid19_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Test string from C to java";
return env->NewStringUTF(hello.c_str());
"()[java/lang/Double;" describes a method expecting no arguments and returning a double array.
jmethodID methodID = env->GetMethodID(MainActivity, "getDouble", "()[java/lang/Double;");
}
jobjectarray doubles = env->CallObjectMethod(MainActivity, methodID);
int index = 0;
jdouble doubleArray = env->GetObjectArrayElement(double, index);
Java code:
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
public double[] getDouble(){
double[] j = {0, 4, 5, 6, 7};
return j;
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
答案1
得分: 1
不,你的方法基本上是正确的。然而,实现有点问题:
- 你应该通过使用
env->GetObjectClass(obj)
来获取对MainActivity
类的引用,其中obj
是你的函数的第二个参数。 getDouble
的签名是()[D
。使用javap -s
来查看正确的签名,而不是猜测。
如果数组很大,你可能要考虑使用 GetDoubleArrayRegion
来获取可以直接读取的 double*
,或者使用 GetDoubleArrayElements
/ReleaseDoubleArrayElements
来进行操作。
英文:
No, your approach is pretty much correct. The implementation is a bit off, however:
- You should get a reference to the
MainActivity
class by usingenv->GetObjectClass(obj)
, whereobj
is the second argument of your function. - The signature of
getDouble
is()[D
. Usejavap -s
to see correct signatures instead of guessing.
If the array is large you might want to consider GetDoubleArrayRegion
to get a double*
you can read directly, or GetDoubleArrayElements
/ReleaseDoubleArrayElements
to manipulate it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论