Calling a function using the context pointer using JNI on android causes a segfault

0

I found this bit of code in one of the example tango projects using the JNI and I have no idea what the context is nor how to use it. The example code works, but my code does not.

void OnXYZijAvailableRouter(void *context, const TangoXYZij *xyz_ij) {
    SynchronizationApplication *app =
        static_cast<SynchronizationApplication *>(context);
    app->OnXYZijAvailable(xyz_ij);
}

I tried mimicking it below:

void OnFrameAvailableRouter(void *context, const TangoCameraId id,
                            const TangoImageBuffer *buffer) {
    SynchronizationApplication *app =
        static_cast<SynchronizationApplication *>(context);
    LOGE("Before onframe call.");
    app->onFrameAvailable(id, buffer);
    LOGE("After onframe call.");
}

When I try to run it, however, I get this output:

Before onframe call.
Fatal signal 11 (SIGSEGV) at 0x00000308 (code=1), thread 15673 (Binder_2)

Now I managed to find the pointer that causes the seg fault, but I have no idea why it does not work.

Naturally, I might have done something wrong, but I have no idea what since I made an exact copy of the code in the example.

int SynchronizationApplication::TangoConnectCallbacks() {
    TangoErrorType depth_ret =
            TangoService_connectOnXYZijAvailable(OnXYZijAvailableRouter);

    depth_ret = TangoService_connectOnFrameAvailable(TangoCameraId::TANGO_CAMERA_COLOR, NULL,
                                         OnFrameAvailableRouter);

    return depth_ret;
}

The functions I call from the routers.

void OnXYZijAvailable(const TangoXYZij *xyz_ij);
void onFrameAvailable(const TangoCameraId id, const TangoImageBuffer *buffer);

What exactly is the context? I have read some explanations, but I still do not understand why I can call the function using the context in the example above, nor why I need the router function at all. I have read this SO answer and the android page on the concept, but I see no link between the context and my class.

android
c++
java-native-interface
google-project-tango
asked on Stack Overflow Jan 27, 2016 by Noobs DeSroobs • edited May 23, 2017 by Community

1 Answer

1

In the OnXYZijAvailableRouter (the depth callback), the context is the instance passed in from the TangoService_connect function. I believe in the application class, there should be a line like this: TangoService_connect(this, tango_config_); So this become the context when the callback is called. This context also applies to pose and event callbacks.

In the case of OnFrameAvailableRouter, the context is the instance you passed in in the TangoService_connectOnFrameAvailable. In this case, the code is setting a NULL as context, but in the callback, it's trying the call a function on NULL. That's the crash point.

I believe if you change the it to TangoService_connectOnFrameAvailable(TangoCameraId::TANGO_CAMERA_COLOR, this, OnFrameAvailableRouter); it should work fine.

The router function is for the callbacks, I haven't find a way of giving a function pointer of a instance to the API. But let me know if you find a way to do that, I would like to know as well..

answered on Stack Overflow Jan 27, 2016 by xuguo

User contributions licensed under CC BY-SA 3.0