【发布时间】:2015-08-24 21:54:51
【问题描述】:
我需要将 C++ 文件集成到我的 Android 应用程序项目中。 我可以构建文件并生成 .so 文件。
这是具有函数 process() 的头文件。 我需要从我的 .java 文件中调用此方法。
class PayrollGenerator {
public:
typedef void (* PAYROLL_READY_CALLBACK) (std::vector<int> list, int id);
typedef void (* PROGRESS_CALLBACK) (int progress);
private:
PAYROLL_READY_CALLBACK _dataReadyCallback;
PROGRESS_CALLBACK _progressCallback;
public:
DataProcessor(PAYROLL_READY_CALLBACK dataReadyCallback, PROGRESS_CALLBACK progressCallback);
void process(int data);
};
有两个回调,它们会给我结果和正在处理的数据的进度数据。 我无法为它设计 JNI 方法。 顺便说一句,我从 .java 文件运行简单的 C++ 程序。 但这对我来说很复杂。 请帮忙 !!
进展 - 我创建了一个 C++ 文件并编写了包装器
JNIEnv *global;
jobject impl;
struct DataProcessorStruct {
jobject callback_ptr;
DataProcessor *dataProcessor;
};
void dataReadyCallback(std::vector<jint> processedSamples, jint heartRate){
jintArray arr = global->NewIntArray( processedSamples.size() );
global->SetIntArrayRegion( arr, 0, processedSamples.size(), ( jint * ) &processedSamples[0] );
jclass clazz = global->FindClass("com/app/AudioActivity");
jmethodID method = global->GetMethodID(clazz, "dataReady","[Ljava/util/List;I)V");
global->CallVoidMethod(impl,method,arr,heartRate);
__android_log_print(ANDROID_LOG_INFO, "test", "C-dataReadyCallback");
}
void progressCallback(jint progress){
jclass clazz = global->FindClass("com/app/AudioActivity");
jmethodID method = global->GetMethodID(clazz, "dataProcessProgress","(I)V");
global->CallVoidMethod(impl, method,progress);
__android_log_print(ANDROID_LOG_INFO, "test", "C-progressCallback");
}
JNIEXPORT jlong JNICALL Java_com_app_AudioActivity_createDataProcessorObject (JNIEnv * env, jobject obj){
global = env;
impl = obj;
DataProcessorStruct *cpp_obj = new DataProcessorStruct();
if (cpp_obj == NULL) {
return 0;
}
DataProcessor *csObj = new DataProcessor(dataReadyCallback,progressCallback);
if (csObj == NULL) {
return 0;
}
cpp_obj->dataProcessor = csObj;
cpp_obj->callback_ptr = env->NewGlobalRef(obj);
return (jlong)cpp_obj;
}
JNIEXPORT void JNICALL Java_com_app_processData (JNIEnv * env, jobject obj,jlong objId,jint sample,jint dataLeft){
impl = obj;
DataProcessorStruct *cpp_obj = (DataProcessorStruct *)objId;
DataProcessor *dataProcessor=cpp_obj->dataProcessor;
if (dataProcessor != NULL){
dataProcessor->process(sample,dataLeft);
}
}
Java 中的本地方法是 -
public native long createDataProcessorObject();
public native void processData(long dataProcessor,int sample, int dataLeft);
这是正确的做法吗? 有什么方法我不必直接从 dataReadyCallback() 和 progressCallback() C++ 方法调用类 Java 方法,但不知何故我可以调用 Java 中的接口方法来从这些 C++ 方法调用,以便任何类监听这些回调应该得到通知,而不是特定的类?
【问题讨论】:
-
您需要在 Java 类型和 C++ 类型之间编组数据。查看SWIG。
-
由于公司政策,我不能使用第三方软件。
-
SWIG 是一种生成代码以编组语言之间调用的工具,如果您的公司禁止您使用让您高效的工具,那么您的公司很糟糕。
-
我尝试了 SWIG,但是当我将 C++ 代码发布到其中时,它没有给出任何结果。
标签: android c++ android-studio java-native-interface