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

我是 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 函数时都初始化向量。

是否有明确定义的方式/模式/技术来做到这一点。

非常感谢任何答案。

最佳答案

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

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

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

java
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);
}

https://stackoverflow.com/questions/23814811/

相关文章:

python - 使用OpenCV计数视频中的帧…(Python)

docker - Docker端口映射在Windows 10上不起作用

android - 如何使用静态OpenCV在Android中使用JavaCV的静态方法

python - GUI 卡住了其余的 python 代码

python - 质心计算程序中的时间滞后

docker - depends_on不等待docker-compose 1.22.0中的其他服务

python - 使用 slider 编辑颜色值

docker - 无法在 Dockerfile 中运行 sysctl 命令

opencv - 更改图像opencv的宽度步长

opencv - OpenCV旋转的图像显示时形状不正确