在JNI / Android中初始化一次C ++对象

时间:2014-05-22 18:43:52

标签: android opencv java-native-interface instantiation

我是Android和JNI的新手。但是在C / C ++方面有丰富的经验。我想弄清楚以下

将VS2013中制作的桌面代码移植到Android。这是一个opencv项目。 我移植了大部分性能代码。 但我无法理解如何初始化某些对象并在某个处理步骤的生命周期内保持它们的存活。

桌面代码的伪代码

vector<contours*> cntrs // Initialized somewhere else

void ProcessFrame(Mat)
{

    LOOP until kb != 'q'
    {
         step 1 - Extract contours and add them to vector<contours> 

         step 2 -  Display contours
    } 
}

在android中,我知道我可以将图像传递给C / C ++代码处理它,然后将其抛回Java。 但我想要的是每次进入我将提取轮廓的主要JNI函数时,我都不想初始化向量。

是否有明确定义的方式/模式/技术。

非常感谢任何答案。

1 个答案:

答案 0 :(得分:1)

C ++中的全局对象是合法的。您可以使用一些特殊的JNI调用来初始化它们,或者依赖于JNI特定的JNI_OnLoad(),它保证在您的本机代码(共享对象,Windows DLL的Android模拟)加载后调用一次。您也可以让编译器负责这种初始化,例如

std::vector<int> global_v  { 1, 1, 2, 3, 5, 8 };

更新:还有另一种相关的设计模式,当JNI调用返回(通常为)一个倾斜的句柄时(实际上,本机对象的本机指针),此句柄进一步用于与此对象对应的所有JNI调用。句柄被C ++取消引用到实际的本机对象,所有处理都涉及到这一点。这是一个例子:

<强>爪哇

package com.demo;
public class FILE {
  public void test1 {
    long file = fopen("/sdcard/test1", "w");
    fputs(file, "abc");
    fclose(file);
  }

  static { System.loadLibrary("FILE"); }
  private static native long fopen(String fname, String fmode);
  private static native long fwrite(long f, String s);
  private static native void fclose(long f);
}

C ++ (使用NDK编译成libFILE.so)

JNIEXPORT jlong JNICALL Java_com_demo_FILE_fopen(JNIEnv *env, jclass cls, jstring fname, jstring fmode)
{
   char *szfname = (*env)->GetStringUTFChars(env, fname, 0);
   char *szmode = (*env)->GetStringUTFChars(env, fmode, 0);
   FILE* f = fopen(szfname, szmode);
   (*env)->ReleaseStringUTFChars(env, fmode, szmode);
   (*env)->ReleaseStringUTFChars(env, fname, szname);
   retrun (jlong)(f);
}

JNIEXPORT jlong JNICALL Java_com_demo_FILE_fputs(JNIEnv *env, jclass cls, jlong jf, jstring s)
{
   char *szs = (*env)->GetStringUTFChars(env, s, 0);
   FILE* f = reinterpret_cast<FILE*>(jf);
   long len = fputs(f, szs);
   (*env)->ReleaseStringUTFChars(env, s, szs);
   retrun len;
}

JNIEXPORT void JNICALL Java_com_demo_FILE_fclose(JNIEnv *env, jclass cls, jlong jf)
{
   FILE* f = reinterpret_cast<FILE*>(jf);
   fclose(f);
}