https://bbs.csdn.net/topics/392264971
再使用c语言调用java代码的时候,选择使用JNI,根据网上的提示已经能够正常跑了,
int mask_name( char* NAME, char * keyValue, char * weight )
{
   /*
    接下来,声明所有希望在程序中使用的变量。
    JavaVMOption options[] 具有用于 JVM 的各种选项设置。
    当声明变量时,确保所声明的JavaVMOption options[] 数组足够大,以便能容纳您希望使用的所有选项。
    在本例中,我们使用的唯一选项就是类路径选项。
    因为在本示例中,我们所有的文件都在同一目录中,所以将类路径设置成当前目录。
    可以设置类路径,使它指向任何您希望使用的目录结构。*/
        JavaVMOption options[4];
        JNIEnv *env;
        JavaVM *jvm;
        JavaVMInitArgs vm_args;
    /*JNIEnv *env          表示 JNI 执行环境。
    JavaVM jvm             是指向 JVM 的指针,我们主要使用这个指针来创建、初始化和销毁 JVM。
    JavaVMInitArgs vm_args 表示可以用来初始化 JVM 的各种 JVM 参数。*/

long status;
        jclass cls;
        jmethodID mid;
        jstring square;

/*avaVMInitArgs 结构表示用于 JVM 的初始化参数。
    在执行 Java 代码之前,可以使用这些参数来定制运行时环境。
    正如您所见,这些选项是一个参数,而 Java 版本是另一个参数。
    按如下所示设置了这些参数:*/

/*为 JVM 设置类路径,以使它能找到所需要的 Java 类。
    在这个特定示例中,因为 Sample2.class 和Sample2.exe 都位于同一目录中,所以将类路径设置成当前目录。
    我们用来为 Sample2.c 设置类路径的代码如下所示:*/
        options[0].optionString = "-Djava.compiler=NONE";
        options[1].optionString = "-Djava.class.path=C:\\algorithmfordm.jar";
        options[2].optionString = "-Djava.library.path=C:\\Program Files\\Java\\jdk1.7.0_03\\jre\\bin\\server";  //指定加载的so路径
        options[3].optionString = "-verbose:NONE"; //用于跟踪运行时的信息
        //options[1].optionString = "-verbose.jni";
        //options[0].optionString = "-Djava.class.path=.";
        memset(&vm_args, 0, sizeof(vm_args));
        vm_args.version=JNI_VERSION_1_6;//jdk版本1.6
        vm_args.nOptions = 4;
        vm_args.options = options;
        vm_args.ignoreUnrecognized = JNI_TRUE;

/*创建 JVM
    处理完所有设置之后,现在就准备创建 JVM 了。先从调用方法开始
    如果成功,则这个方法返回零,否则,如果无法创建 JVM,则返回JNI_ERR。*/

status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
        printf("--------------------****%ld\n",status);
        if (status != JNI_ERR)
        {
    /*
    查找并装入 Java 类
    一旦创建了 JVM 之后,就可以准备开始在本机应用程序中运行 Java 代码。
    首先,需要使用FindClass() 函数查找并装入 Java 类,如下所示:
    cls 变量存储执行FindClass() 函数后的结果,如果找到该类,则 cls 变量表示该Java 类的句柄,
    如果不能找到该类,则 cls 将为零。
    */
            cls = (*env)->FindClass(env, "com/wiseweb/algorithm/MobilePhoneFilterAlgorithm");
            //(*env)->FindClass(env, "jni/JniTest");
            printf("test1,cls=%d...\n",cls);

if(cls !=0)
            {
    /*
    查找 Java 方法
    接下来,我们希望用 GetStaticMethodID() 函数在该类中查找某个方法。
    我们希望查找方法 intMethod,它接收一个 int 参数并返回一个 int。
    以下是查找 intMethod 的代码:
    */
                mid = (*env)->GetStaticMethodID(env, cls, "getModelMobilePhone", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
                //mid = (*env)->GetStaticMethodID(env, cls, "getObjectMethod", "(Ljava/lang/Object;)Ljava/lang/Object;");

/*
    mid 变量存储执行 GetStaticMethodID() 函数后的结果。
    如果找到了该方法,则 mid 变量表示该方法的句柄。
    如果不能找到该方法,则mid 将为零。
    */
                if(mid !=0)
                {
    /*CallStaticIntMethod() 方法接受 cls(表示类)、mid(表示方法)以及用于该方法一个或多个参数。
    在本例中参数是 int 5。*/
                    //char * p = "422202199109300010";
char showTime[20];
char * t = getTime(showTime);
                    jstring value = (*env) ->NewStringUTF(env , NAME);
                    //char *str = (char *)(*env)->GetStringUTFChars(env,value,0);
                    //printf("%s\n",str);
                    jstring keyvalue = (*env) ->NewStringUTF(env , keyValue);
                    jstring timevalue1 = (*env) ->NewStringUTF(env , t);
                    jstring quanzhi = (*env) ->NewStringUTF(env , weight);
                    square = (jstring)(*env)->CallStaticObjectMethod(env, cls, mid,value,keyvalue,timevalue1,quanzhi);
                    //square = (*env)->CallStaticIntMethod(env, cls, mid,4);
                    char *str1 = (char *)(*env)->GetStringUTFChars(env,square,0);
                    //printf("%s\n",str1);
                    memset(NAME,0X00,11);
                    if(strcmp(NAME, str1) != 0){
                        int i ;
                        for(i = 0; i < strlen(str1); i++){
                          NAME[i] = str1[i];
                        }
                    }
                }
            }
             if ((*env)->ExceptionOccurred(env)) {

(*env)->ExceptionDescribe(env);

}
            jint end = (*jvm)->DestroyJavaVM(jvm);
            printf("-------------00000000000--%d\n",end);
            return 0;

}
        else
        {
            return -1;

}

}

int main()
{
    int k ;
    for(k = 0; k < 3; k++){
        char NAME[] = {"15007113427"};
        char keyValue[] = {"457685645971234574"};
        char weight[] = {"40"};
        mask_name(NAME,keyValue,weight);
    //printf("Hello world!%d\n",sizeof(NAME));
        printf("-----------------------11111111111--------%s\n",NAME);

}
    system ("pause");
    return 0;
}

问题点数:40分
   
0 2017-09-18 12:46:58
引用 ・ 举报 ・ 管理 #1 得分:0
不要做A语言代码修改为B语言代码的无用功。
也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。
只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。
即可很方便地让A、B两种语言之间协调工作。
比如:
A将请求数据写到文件a.txt,写完后改名为aa.txt
B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,再将b.txt改名为bb.txt
A发现bb.txt存在时,读取其内容,读完后删除bb.txt
以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。
除非A或B不支持判断文件是否存在、文件读写和文件更名。
但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢?
可以将临时文件放在RamDisk上提高效率减少磨损磁盘。
数据的结构很复杂的话,文本文件的格式问题可参考json或xml

共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的:
·进程之间松耦合
·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。
·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。
·方便在线开关服务,只需删除或创建该临时文本文件即可。
·方便实现分布式和负载均衡。
·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满)
·……

“跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边,
回头是“使用共享纯文本文件进行信息交流”的岸!

 
0 2017-09-19 16:02:34
引用 ・ 举报 ・ 管理 #2 得分:0
您好 ,   跨语言并非我所愿,只是因为需求是这样的,本来运行IBM的optim的脱敏函数接口是用C语言开发的。但是客户需要我们用他们的算法,而且不给算法我们,只给我一个jar包让我们调用,现在大部分难点都慢慢解决了 ,但是卡在c语言重复调用jar包的问题上了,希望赵老师能给我提供一点思路
   
0 2017-09-20 13:24:38
引用 ・ 举报 ・ 管理 #3 得分:40
c语言通过读写临时文本文件,间接调用java写的读写相同临时文本文件并调用jar包的程序。
0 2017-09-20 14:56:02
引用 ・ 举报 ・ 管理 #4 得分:0
jvm 在进程内就是只能初始化一次的,
你把jvm寄宿从功能调用中分离出来单独初始化
  
0 2017-09-20 14:38:22
引用 ・ 举报 ・ 管理 #5 得分:0
直接通过命令行调用更简单:
java -jar xxx.jar param1 param2... >out.txt
其中param1等是传入的命令行参数,数据可以作为参数传入,或者作为文件名传入。
然后通过读取out.txt获取它的运行结果。

 
0 2017-09-21 13:12:10
引用 ・ 举报 ・ 管理 #6 得分:0
因为代码开发的是dll文件 ,不能单独初始化,  我选择将java虚拟机做成静态,但是注销虚拟机这个操作就没法进行了。感谢大家的帮助,这个贴我结了!
 
0 2018-03-02 10:16:33
引用 ・ 举报 ・ 管理 #7 得分:0
你好,关于用jni调用java虚拟机,JNI_CreateJavaVM后,DestroyJavaVM,然后在JNI_CreateJavaVM出错了,返回-1,这个要怎么解决,还望指点一二,谢谢
 
0 2018-03-30 16:29:39
引用 ・ 举报 ・ 管理 #8 得分:0
在执行c调用java的过程中只要执行一次JNI_CreateJavaVM,结束之后在执行DestroyJavaVM,不要把JNI_CreateJavaVM执行多次

C调用java JNI_CreateJavaVM只能调用成功一次的更多相关文章

  1. 通过JNI实现java调用C代码和C代码调用java的代码

    一.java调用C代码 1)java中需要声明调用的函数,也就是native方法,并通过System.LoadLibrary来调用dll或者so(C代码).实例代码如下: public class H ...

  2. oracle调用JAVA类的方法

    导入jar包 在oracle中导入需要的jar包,我们把编辑好的java类打成jar包,直接在oarcle里面写简单的调用就可以了,  1.操作系统需要拥有支持loadjava命令的jdk.  2.加 ...

  3. Oracle触发器反向调用Java程序

    导入jar包 在oracle中导入需要的jar包,我们把编辑好的java类打成jar包,直接在oarcle里面写简单的调用就可以了, 1.操作系统需要拥有支持loadjava命令的jdk. 2.加载j ...

  4. Android NDK开发之C调用Java及原生代码断点调试(二)

    上一篇中,我们主要学习了Java调用本地方法,并列举了两大特殊实例来例证我们的论据,还没学习的伙伴必须先去阅读下,本次的学习是直接在上一篇的基础上进行了.点击:Android NDK开发之从Java与 ...

  5. Java与WCF交互(二):WCF客户端调用Java web service【转】

    原文:http://www.cnblogs.com/downmoon/archive/2010/08/25/1807982.html 在上篇< Java与WCF交互(一):Java客户端调用WC ...

  6. 转载——Java与WCF交互(二):WCF客户端调用Java Web Service

    在上篇< Java与WCF交互(一):Java客户端调用WCF服务>中,我介绍了自己如何使用axis2生成java客户端的悲惨经历.有同学问起使用什么协议,经初步验证,发现只有wsHttp ...

  7. 基于 Android NDK 的学习之旅----- C调用Java

    许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现. 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态 ...

  8. Android JNI入门第六篇——C调用Java

    本篇将介绍在JNI编程中C调用Java实现. 源码下载地址:http://download.csdn.net/detail/xyz_lmn/4868265 关键代码: java: public cla ...

  9. 第4篇-JVM终于开始调用Java主类的main()方法啦

    在前一篇 第3篇-CallStub新栈帧的创建 中我们介绍了generate_call_stub()函数的部分实现,完成了向CallStub栈帧中压入参数的操作,此时的状态如下图所示. 继续看gene ...

随机推荐

  1. C语言strcasecmp()函数:判断字符串是否相等(忽略大小写)

    头文件:#include <string.h> 定义函数:int strcasecmp (const char *s1, const char *s2); 函数说明:strcasecmp( ...

  2. SpringMVC的Model ModeMap ModelAndView @ModelAttribute @SessionAttribute区分

    Spring MVC整理系列(05)————Spring MVC配置解析及整合SpriSpring MVC之@ModelAttribute.@SessionAttributes以及Model的使用介绍 ...

  3. Nodejs基础(5-6)HTTP概念进阶

    1.什么是回调? 是异步编程最基本的方法,对于nodejs来说需要按顺序执行异步逻辑的时候一般采用后续传递的方式,也就是将后续逻辑封装在回调函数中作为起始函数的参数逐层去嵌套.通过这种方式来让程序按照 ...

  4. jmeter BeanShell断言(一)

    原文地址https://blog.csdn.net/lijing742180/article/details/81157947 原文地址https://blog.csdn.net/zailushang ...

  5. Cocos2d-JS studio基础控件的使用

    在studio里把几个基础控件往场景文件一拖,然后导出json格式的资源文件 逻辑代码如下: 1 var HelloWorldLayer = cc.Layer.extend({ 2 sprite:nu ...

  6. HDU 4565 So Easy(矩阵解公式)

    So Easy [题目链接]So Easy [题目类型]矩阵解公式 &题解: 感觉这种类型的题都是一个套路,这题和hdu 2256就几乎是一样的. 所以最后2Xn就是答案 [时间复杂度]\(O ...

  7. linux----------wdcp(是一款集成的linux环境)中的各种坑。

    1.刚买的空间客服给安装了wdcplinux,结果上去一看PHP是5.2版本的,这不是搞笑嘛.然后就有了下面的升级: 复制这条命令回车然后敲Y就可以: wget http://soft.itbulu. ...

  8. MyBatis基础入门《七》查询参数传入对象

    MyBatis基础入门<七>查询参数传入对象 描述: 在执行查询语句的时候,传入的参数是一个对象,依据对象的属性,进行检索数据.此时,书写SQL语句中的条件时,其参数需要和对象中的属性保持 ...

  9. laravel orm

    ###多对多关系 多对多关系和之前的关系完全不一样,因为多对多关系可能出现很多冗余数据,用之前自带的表存不下了. 我们定义两个模型:Article 和 Tag,分别表示文章和标签,他们是多对多的关系. ...

  10. <6>Lua元表和冒号 self

    Lua中没有像C.C++.JAVA中的类概念,面向对象等 ,但我们可以模拟出来 1. Lua中有个很重要的概念元表 设置元表setmetatable()函数  获取元表getmetatable()函数 ...