andorid ndk 各种坑啊 记录下

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了andorid ndk 各种坑啊 记录下相关的知识,希望对你有一定的参考价值。

android jni代码回调java的问题
因为多线程原因会导致找不到java类,无法call函数的问题
问题1找不到java类
在JNI_OnLoad的时候 保存下来

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
    g_vm = vm;
    JNIEnv* env = NULL;
    jint result = -1;
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        return -1;
    }
    assert(env != NULL);

    register_location_methods(env);
    result = JNI_VERSION_1_4;
    return result;
}
int register_location_methods(JNIEnv *env)
{
    jniEnv = env;
    jclass clazz;
    clazz = env->FindClass("com/TongBan/Chat/NetBilling");
    if (clazz == NULL) {
        return -1;
    }
    JNetBilling = clazz;

    onReceivedMsgType = env->GetStaticMethodID(clazz,
                    "OnReceivedMsgType", "(I)V");
//    env->CallStaticVoidMethod(JNetBilling, onReceivedMsgType, 1);
    return 0;
}

问题2多线程回调call函数
此处生成的JNIEnv无法获取到class 函数 等 须要之前保存好的全局变量

bool isAttacked = false;
    JNIEnv* env;
    int status = g_vm->GetEnv((void **) &env, JNI_VERSION_1_4);
    if (status < 0) {
        status = g_vm->AttachCurrentThread(&env, NULL);
        if (status < 0) {
            return len;
        }
        isAttacked = true;
    }
    env->CallStaticVoidMethod(JNetBilling,onReceivedMsgType,iMsgType);
    if (isAttacked) {
        g_vm->DetachCurrentThread();
    }

输出问题因为还是比較喜欢cout就百度了个cout输出到logCat日志的

int iMsgType = MSG_PACKET::GetMsgType(kBuffer);

    StreamBuf g_StreamBuf;
    std::cout.rdbuf(&g_StreamBuf);
    std::cout << iMsgType;//就可以显示到logCat
#include <iostream>
#include <streambuf>

class StreamBuf : public std::streambuf
{
    enum
    {
        BUFFER_SIZE = 255,
    };

public:
    StreamBuf()
    {
        buffer_[BUFFER_SIZE] = ‘\0‘;
        setp(buffer_, buffer_ + BUFFER_SIZE - 1);
    }

    ~StreamBuf()
    {
        sync();
    }

protected:
    virtual int_type overflow(int_type c)
    {
        if (c != EOF)
        {
            *pptr() = c;
            pbump(1);
        }
        flush_buffer();
        return c;
    }

    virtual int sync()
    {
        flush_buffer();
        return 0;
    }

private:
    int flush_buffer()
    {
        int len = int(pptr() - pbase());
        if (len <= 0)
            return 0;

        if (len <= BUFFER_SIZE)
            buffer_[len] = ‘\0‘;

#ifdef ANDROID
        android_LogPriority t = ANDROID_LOG_INFO;
        __android_log_write(t, "JNI_DEBUG", buffer_);
#else
        printf("%s", buffer_);
#endif

        pbump(-len);
        return len;
    }

private:
    char buffer_[BUFFER_SIZE + 1];
};

到这里 最终能够 互动了 android->server->android

以上是关于andorid ndk 各种坑啊 记录下的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向Android 进程注入工具开发 ( Visual Studio 开发 Android NDK 应用 | Visual Studio 中 SDK 和 NDK 安装位置 )(代码片段

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

NDK: ant 错误 [javah] Exception in thread "main" java.lang.NullPointerException 多种解决办法(代码片段

DetachCurrentThread有时会在NDK中崩溃

NDK编译FFMpeg[Linux]

记录一个问题android ndk下设置线程的亲缘性,总有两个核无法设置成功