V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
init
V2EX  ›  问与答

c 如何给 java 层发送信息

  •  
  •   init · 2016-08-23 14:01:18 +08:00 · 2654 次点击
    这是一个创建于 2774 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在的情况是这样的 java 通过 jni 调用 c 的接口, c 是被动的 目前有这么一个需求 c 层一旦发生更新那么 c 要主动告知 java 层 c 更新了

    不知道有什么方法能实现? jni 可不可以呢?

    12 条回复    2016-08-23 23:40:27 +08:00
    zts1993
        1
    zts1993  
       2016-08-23 14:04:58 +08:00
    socket?
    nicevar
        2
    nicevar  
       2016-08-23 14:23:41 +08:00   ❤️ 1
    jni 当然可以了,你做个回调就可以了,比如传递一个 java 对象给 c 层,然后 c 层回调的时候通过 JNIEnv 查找 java 对象的 jmethodID 进行调用就行了
    init
        3
    init  
    OP
       2016-08-23 15:12:46 +08:00
    @nicevar c 层回调的时候通过 JNIEnv 查找 java 对象的 jmethodID 进行调用就行了--->这个不是很理解能不能简单写个 demo 呢
    这是我写的
    JNIEXPORT jboolean JNICALL Java_com_control_notifyModemByLogic
    (JNIEnv *env, jobject obj, jint slot, jstring imsi_str)
    {

    //1.找到 control 代码的 class 文件
    jclass controlManager = (*env)->FindClass(env, "com//control/Manager");
    //2. 寻找 class 的静态方法
    jmethodID notifyModem = (*env)->GetStaticMethodID(env, controlManager, "notifyModemByLogic", "(ILjava/lang/String;)Z");

    //3.调用 control 的方法
    jboolean notifyResult= (*env)->CallStaticBooleanMethod(env, controlManager, notifyModem,slot,imsi_str);

    return notifyResult;

    }

    我不知道这样写对不对。。。感觉这样写 c 还是不能调用接口, 比如那几个形参生成呢?
    nicevar
        4
    nicevar  
       2016-08-23 15:31:37 +08:00
    @init 别凭感觉啊,你上面那个包名多了个杠,你上面的静态方法也是可以的,参数是一个 int+一个 String 类型,返回布尔值,你在这个静态类里面做接收就行了,动态对象的我写个简单的
    int action = 1;
    char* value = "xxoo";
    jclass native_class = env->GetObjectClass(obj);//obj 是一个 java 传递过来接受回调的对象,类名随便你
    jmethodID mId = env->GetMethodID(native_class, "SomeCallback", "(ILjava/lang/String;)V");//SomeCallback 是上面对象的一个方法,带有一个 int,string 参数,返回值是 void ,假如是 boolean 就写 Z
    jstring jValue = env->NewStringUTF(value);
    env->CallObjectMethod(obj, mId, action, jValue);//传递参数
    init
        5
    init  
    OP
       2016-08-23 15:50:27 +08:00
    @nicevar 有个小疑问,这里首先应该是 java 层发起调用吧

    obj,env obj,env (形参)
    java----------->jni----------->c

    我说的对吗?

    但是我需要的是这样的

    java<---------jni<------------c(检测到更行需要向 java 通知)

    c 那边首先调用相关接口通知 java ,调用的话 相关的 obj env 应该找不到的吧
    nicevar
        6
    nicevar  
       2016-08-23 16:02:31 +08:00
    @init java------>jni------->c 这个过程 java 传递一个 obj 给 c , c 什么时候想通知 java 都行了
    上面我写的就是 c 调用通知 java 的过程啊
    Mithril
        7
    Mithril  
       2016-08-23 16:09:55 +08:00
    你可以看看 SWIG 项目和它生成的代码。
    它生成的 Wrapper 支持 Java 向 C 里面传回调。
    mcxiaoke
        8
    mcxiaoke  
       2016-08-23 18:11:18 +08:00
    Lonely
        9
    Lonely  
       2016-08-23 19:24:23 +08:00 via Android
    谷歌一下大把的答案
    SoloCompany
        10
    SoloCompany  
       2016-08-23 22:49:29 +08:00
    你到底是写 c 还是写 java 的,怎么会有 jni 只能是 java 是调用方 c 只能是被调用方这种错觉
    northisland
        11
    northisland  
       2016-08-23 23:39:01 +08:00 via Android   ❤️ 1
    ZeroMQ
    northisland
        12
    northisland  
       2016-08-23 23:40:27 +08:00 via Android
    Pair,REPREQ,PUSHPULL 模型都适合。 zeroMQ
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1212 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:14 · PVG 07:14 · LAX 16:14 · JFK 19:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.