C++;导致本机Android崩溃的库 我正在学习如何将C++项目实现为本地Android,并发现自己是一个导入的C++库。一切都很好,但是问题是当代码> OnButlook()//Cube被调用时,用户按预期被指向前一个片段,但是当它们重新进入由C++库填充的活动时,就会发生崩溃。

C++;导致本机Android崩溃的库 我正在学习如何将C++项目实现为本地Android,并发现自己是一个导入的C++库。一切都很好,但是问题是当代码> OnButlook()//Cube被调用时,用户按预期被指向前一个片段,但是当它们重新进入由C++库填充的活动时,就会发生崩溃。,android,c++,java-native-interface,Android,C++,Java Native Interface,我得到的唯一错误是A/libc:Fatal signal 11(SIGSEGV)、code 1(SEGV_MAPERR)、tid 9408中的fault addr 0x8(GLThread 27055)、pid 9296(流体模拟) 我开始在代码> GLYCODCONT.CPP文件中进行挖掘,在这里我将值传递给暴露的C++方法,我相信我已经确定了这个问题,但是我被困在了一个修复……/P> 有以下C++方法,每次创建活动时调用:< /P> //This is global as it is use

我得到的唯一错误是
A/libc:Fatal signal 11(SIGSEGV)、code 1(SEGV_MAPERR)、tid 9408中的fault addr 0x8(GLThread 27055)、pid 9296(流体模拟)

我开始在代码> GLYCODCONT.CPP文件中进行挖掘,在这里我将值传递给暴露的C++方法,我相信我已经确定了这个问题,但是我被困在了一个修复……/P>

有以下C++方法,每次创建活动时调用:< /P>

//This is global as it is used in other methods
void *fluid; 

extern "C" JNIEXPORT void JNICALL
Java_com_android_ui_fluidSimulation_FluidLib_init(JNIEnv *env, jobject obj, jint width,
                                                  jint height) {
    fluid = fluidCreate((int) width, (int) height);
} 
现在,我发现调用
onBackPressed()
时,退出活动后,
fluid
指针被保存在内存中。我已经计算出每次活动开始时都需要调用此方法,但我需要了解如何重置指针

我尝试了
删除流体fluidCreate
之前执行code>,但这不起作用。这个问题有解决办法吗?还是我听任图书馆摆布,放弃它更好

更新1

所以,每一帧调用下面的方法,我注意到当流体添加到帧中时会发生碰撞

static double now_ms(void) {

    struct timespec res;
    clock_gettime(CLOCK_REALTIME, &res);
    return 1000.0 * res.tv_sec + (double) res.tv_nsec / 1e6;

}

extern "C" JNIEXPORT void JNICALL
Java_com_android_ui_fluidSimulation_FluidLib_step(JNIEnv *env, jobject obj) {

    double t = now_ms();
    //Below is printed
    __android_log_write(ANDROID_LOG_ERROR, "Tag", "Gets before fluidOnFrame");
    fluidOnFrame(fluid, t);
    //Below is is not printed
    __android_log_write(ANDROID_LOG_ERROR, "Tag", "Gets after fluidOnFrame");
}
这些方法在本机Android中调用如下:

private class Renderer : GLSurfaceView.Renderer {

    override fun onDrawFrame(gl: GL10) {
        FluidLib.step()
    }

    override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {

        FluidLib.init(width, height)

    }

    override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
        // Do nothing.
    }
}
object FluidLib {
/**
 * @param width the current view width
 * @param height the current view height
 */
external fun init(width: Int, height: Int)
external fun destroy()
external fun step()

init {
    System.loadLibrary("gl_code")
  }
}
void *fluid;
void *newFluid;

extern "C" JNIEXPORT void JNICALL

Java_com_android_ui_fluidSimulation_FluidLib_init(JNIEnv *env, jobject obj, jint width,
                                                  jint height) {

    if(fluid == 0) {
        fluid = fluidCreate((int) width, (int) height);
    }else{
        newFluid = fluidCreate((int) width, (int) height);
    }

}
使用的方法定义如下:

private class Renderer : GLSurfaceView.Renderer {

    override fun onDrawFrame(gl: GL10) {
        FluidLib.step()
    }

    override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {

        FluidLib.init(width, height)

    }

    override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
        // Do nothing.
    }
}
object FluidLib {
/**
 * @param width the current view width
 * @param height the current view height
 */
external fun init(width: Int, height: Int)
external fun destroy()
external fun step()

init {
    System.loadLibrary("gl_code")
  }
}
void *fluid;
void *newFluid;

extern "C" JNIEXPORT void JNICALL

Java_com_android_ui_fluidSimulation_FluidLib_init(JNIEnv *env, jobject obj, jint width,
                                                  jint height) {

    if(fluid == 0) {
        fluid = fluidCreate((int) width, (int) height);
    }else{
        newFluid = fluidCreate((int) width, (int) height);
    }

}
<>我的文件与C++库交互:

/**
 * C-Style API to enable the fluid component to be used with C-based clients (i.e. Swift)
 */

#ifndef Fluid_h
#define Fluid_h

enum PointerType {
    MOUSE = 0,
    TOUCH = 1,
    PEN = 2
};

#ifdef __cplusplus
extern "C" {
#endif

    void* fluidCreate(int width, int height);  
    void fluidOnFrame(void* fluidPtr, double frameTime_ms);

#ifdef __cplusplus
}
#endif

#endif /* Fluid_h */
更新2

为了更好地理解问题的原因,我最终在我的
fluidCreate
方法周围创建了一个if语句,以查看它是指针还是其他问题,如下所示:

private class Renderer : GLSurfaceView.Renderer {

    override fun onDrawFrame(gl: GL10) {
        FluidLib.step()
    }

    override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {

        FluidLib.init(width, height)

    }

    override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
        // Do nothing.
    }
}
object FluidLib {
/**
 * @param width the current view width
 * @param height the current view height
 */
external fun init(width: Int, height: Int)
external fun destroy()
external fun step()

init {
    System.loadLibrary("gl_code")
  }
}
void *fluid;
void *newFluid;

extern "C" JNIEXPORT void JNICALL

Java_com_android_ui_fluidSimulation_FluidLib_init(JNIEnv *env, jobject obj, jint width,
                                                  jint height) {

    if(fluid == 0) {
        fluid = fluidCreate((int) width, (int) height);
    }else{
        newFluid = fluidCreate((int) width, (int) height);
    }

}
然后对我的方法(称为“每帧”)执行以下操作:

extern "C" JNIEXPORT void JNICALL
Java_com_android_ui_fluidSimulation_FluidLib_step(JNIEnv *env, jobject obj) {

    double t = now_ms();

    if(newFluid == 0) {
        __android_log_write(ANDROID_LOG_ERROR, "Tag", "Original Fluid on Frame");
        fluidOnFrame(fluid, t);
    }else{
        __android_log_write(ANDROID_LOG_ERROR, "Tag", "New Fluid on Frame");
        fluidOnFrame(newFluid, t);
    }
}

现在,即使使用了不同的指针,但仍然会导致崩溃,这使得我认为C++库中有一个错误:代码>流框> <代码>方法…< /p> < p>我认为你是正确的方向。崩溃日志在我看来也是一个内存异常,我认为内存没有被正确释放

退出活动时,需要销毁
流体
指针。我想推荐编写另一个函数,如下所示

extern "C" JNIEXPORT void JNICALL
Java_com_android_ui_fluidSimulation_FluidLib_destroy(JNIEnv *env) {
    delete fluid;
}
并在
活动
暂停
恢复
函数中调用此函数


我希望这将破坏内存引用,并避免您遇到的
致命信号11(SIGSEGV)
崩溃问题

感谢您的建议-我尝试过,但仍然遇到相同的错误-我在第一次调用
fluidCreate
时放置了一个日志,最初我得到
fluid=0
,然后在调用onPause-Log confims时调用您建议的方法,然后,我启动一个新的fluid会话,在调用
fluidCreate
之前检查指针值,即使使用了您的方法,日志也会显示fluid的值为:
fluid=-1065261744
,我想这是意料之中的。当您删除了
流体
的引用时,它应该有一个无效的内存位置,因此当您试图在日志中获取
流体
时,在再次创建它之前,它给了你<代码> -1065261744 ——我想说。我想知道代码中的一些变量是否是FLUIDCREATEXE//COD>函数没有被正确地释放。好吧,对不起我的无知,我对C++的经验很小。没错,当我在
fluidCreate
方法之后登录时,指针被重新分配。我将继续研究这个问题。唯一需要注意的是,我有一个方法,每帧调用一次,将流体添加到屏幕上,它在这里崩溃。然而,它所采用的唯一参数是流体和时间戳:
fluidinframe(流体,t)。所以我仍然相信
流体
指针是某种原因。。。