当前位置: 首页 > news >正文

做那种的视频网站有哪些/网络营销模式有哪些

做那种的视频网站有哪些,网络营销模式有哪些,北京网站建设团队,做哪个视频网站赚钱最近搞了一个调用第三方so库做登录认证的任务,以前对JNI没什么概念,最近学习了 《java核心技术》 本地方法 一章,把自己写的一些例子记录一下。 自己C语言真是渣渣,所以所有的例子都在可以包括基本API的基础上尽可能简单。以下所有…

最近搞了一个调用第三方so库做登录认证的任务,以前对JNI没什么概念,最近学习了 《java核心技术》 本地方法 一章,把自己写的一些例子记录一下。 自己C语言真是渣渣,所以所有的例子都在可以包括基本API的基础上尽可能简单。以下所有例子都是在centos 7中测试的,window不太熟。

调用本地方法

java调用本地方法,首先需要加载包含对应方法的so库(linux),一般使用下面这种方式加载so库。

1 public class Test{
2         static
3         {
4                 //so库的名字是libTest.so
5                 System.loadLibrary("Test");
6         }
7 
8         public static native void hello();
9 }

 

在static代码块中加载so库,这样就能在这个类被classLoader 加载的时候就被载入。要想正确载入so,必须将so库放在java.library.path 指定的路径中,我们可以通过以下两种方式来指定java.library.path 的值

1. 配置 LD_LIBRARY_PATH 环境变量

2. 通过java的运行参数指定 -Djava.library.path= .....  

 

当我们调用本地方法时,会在加载的so库中去寻找与我们所调用方法对应的本地方法,比如上面定义的hello方法,就应该有一个对应的本地方法为 

JNIEXPORT void JNICALL Java_Test_hello(JNIEnv *, jclass)

我们可以使用javah产生这个一个头文件,在其中就包含了这个方法的声明。

我们编写完c文件后,就可以用它生成一个对应的so了

gcc -fPIC -I jdk/include -I jdk/include/linux -shared -o libTest.so Test.c

其中jdk是含有jdk的目录,以我的环境为例,jdk目录为 /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.79-2.5.5.1.el7_1.x86_64/, 配置JAVA_HOME指向这个目录,所以编译命令就是:

gcc -fPIC -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/linux -shared -o libTest.so Test.c

之所以要使用-I 参数指定这两个目录,是因为在其中包含了c文件需要的两个头文件, <jni.h>和 <jni_md.h>

总结出将一个本地方法链接到java程序中的步骤:

1)在java类中声明一个native方法

2)运行javah 得到一个本地方法需要的头文件

3)使用C实现本地方法

4)使用C代码编译出so文件,并将它放置在java.library.path中

5)使用java调用就可以了

 下面的案例中重要的api都用红色标记了。

案例1:

计算两个int的和(传入int参数并返回int类型)

class Calc
{static{System.loadLibrary("Calc");}public static native int add(int a, int b);public static void main(String[] args){System.out.println(add(11,23));}
}

 

对应的C代码:

#include <stdio.h>
#include "Calc.h"/* jint 对应着java 的int类型  */
JNIEXPORT jint JNICALL Java_Calc_add(JNIEnv *env, jclass jc, jint a, jint b)
{jint ret = a + b;return ret;
}

 

 

案例二:给传入的name加上hello前缀再返回(传入String参数并返回String类型)

class Hello
{static{System.loadLibrary("Hello");}public static native String hello(String name);public static void main(String[] args){System.out.println(hello("zhangsan"));}
}

 

对应的C代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Hello.h"/*拼接字符串 */
char* join(const char *s1, const char *s2)  
{  char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator  //in real code you would check for errors in malloc here  if (result == NULL) exit (1);  strcpy(result, s1);  strcat(result, s2);  return result;  
}  JNIEXPORT jstring JNICALL Java_Hello_hello(JNIEnv* env, jclass cl, jstring name)
{/* 从java String 获得 C char*  */const char* cname;cname = (*env)->GetStringUTFChars(env, name, NULL);char* hello_s = join("hello, ", cname);/* 从 C char* 再获得 java String */jstring ret = (*env)->NewStringUTF(env, hello_s);/* 主动释放内存, 表明不再需要通过 name 来访问 cname*/(*env)->ReleaseStringUTFChars(env, name, cname);return ret;
}

 

案例三: 在C代码中调用PrintWriter.print方法(调用java对象的实例方法)

感觉这种调用和反射基本类似。

import java.io.*;public class Hello
{static{System.loadLibrary("Hello");}public static native void sayHello(PrintWriter out, String message);public static void main(String[] args){PrintWriter out = new PrintWriter(System.out);Hello.sayHello(out, "Hello world!\n");out.flush();}}

 

C代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Hello.h"/*java 的Object类型对应jobject */
JNIEXPORT void JNICALL Java_Hello_sayHello(JNIEnv* env, jclass jc, jobject out, jstring message)
{const char* cmessage;/*从 java String 得到 c char*  */cmessage = (*env)->GetStringUTFChars(env, message, NULL);/* 处理得到的字符串,加上前缀 */const char* append = "I'm say: ";char* result = (char*)malloc(strlen(cmessage) + strlen(append) + 1);strcpy(result, append);strcat(result, cmessage);/*从 c char* 得到 java String */jstring jresult = (*env)->NewStringUTF(env, result);/* 主动释放, 不再需要通过message获得cmessage */(*env)->ReleaseStringUTFChars(env, message, cmessage);/* 下面就是 调用PrintWriter.print(String) *//* 获得class */jclass class_PrintWriter = (*env)->GetObjectClass(env, out);/* 获得 method ID , 最后一个参数是 print方法的签名 返回值为void(V), 参数为java.lang.String */jmethodID id_print = (*env)->GetMethodID(env, class_PrintWriter, "print", "(Ljava/lang/String;)V");/* 调用方法 */(*env)->CallVoidMethod(env, out, id_print, jresult);
}

 

 

案例四: 在C代码中调用System.getProperty静态方法(调用java静态方法)

public class Test
{static{System.loadLibrary("Test");}public static native String getClassPath();public static void main(String[] args){System.out.println(getClassPath());}}

 

c代码实现:

#include <stdio.h>
#include "Test.h"JNIEXPORT jstring JNICALL Java_Test_getClassPath(JNIEnv* env, jclass jc)
{/*获得System的class */jclass class_System = (*env)->FindClass(env, "java/lang/System");/*获得 getProperty 方法的 方法id */jmethodID id_getProperty = (*env)->GetStaticMethodID(env, class_System, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");/* 执行 静态方法 */jobject obj_ret = (*env)->CallStaticObjectMethod(env, class_System, id_getProperty, (*env)->NewStringUTF(env, "version"));return (jstring)obj_ret;
}

 

 这个例子在运行的时候 增加 -Dversion=xxxx 就可以得到version运行参数了。

案例五: 在C中修改Employee的静态和实例属性(修改实例属性和静态属性)

public class Employee
{static{System.loadLibrary("Employee");}public static String a  = "Good Employee";private String name;private double salary;public Employee(String name, double salary){this.name = name;this.salary = salary;}public String toString(){return name + " " + salary;}public native void raiseSalary(double byPercent);public static native void updateDescription(String description);public static void main(String[] args){Employee e = new Employee("zhangsan", 1000);System.out.println(e);e.raiseSalary(0.1);System.out.println(e);System.out.println("###############################");System.out.println(e.a);Employee.updateDescription("Bad Employee");System.out.println(e.a);}
}

 

 c代码:

#include <stdio.h>
#include "Employee.h"JNIEXPORT void JNICALL Java_Employee_raiseSalary(JNIEnv* env, jobject this_obj, jdouble byPercent)
{/* get the class */jclass class_Employee = (*env)->GetObjectClass(env, this_obj); /* get the field Id */jfieldID id_salary = (*env)->GetFieldID(env, class_Employee, "salary", "D"); //"D" 代表类型double/* get the field value  */jdouble salary = (*env)->GetDoubleField(env, this_obj, id_salary);salary *= 1 + byPercent / 100;/* set the field value */(*env)->SetDoubleField(env, this_obj, id_salary, salary);
}JNIEXPORT void JNICALL Java_Employee_updateDescription(JNIEnv* env, jclass jc, jstring description)
{/* get static class field *//*一定要注意类的签名方式, 前面的L 和最后的;(分号)都不能少,那个分号不是分隔符,是签名的一部分 */jfieldID desc_id = (*env)->GetStaticFieldID(env, jc, "a", "Ljava/lang/String;");    /* set new static description field */(*env)->SetStaticObjectField(env, jc, desc_id, description);
}

 

 案例六:访问修改数组

class Test
{static{System.loadLibrary("Test");}public static native void scaleArray(double[] arr);public static void main(String[] args){double[] arr = {1.1, 2.2};scaleArray(arr);for(double d : arr){System.out.println(d);}}
}

 

C代码实现:

#include <stdio.h>
#include "Test.h"JNIEXPORT void JNICALL Java_Test_scaleArray(JNIEnv* env, jclass jc, jdoubleArray arr)
{double scaleFactor = 2.0;/*获得 一个指向 数组的指针 */double* a = (*env)->GetDoubleArrayElements(env, arr, NULL);int i;for(i = 0; i< (*env)->GetArrayLength(env, arr); i++)a[i] = a[i] * scaleFactor;(*env)->ReleaseDoubleArrayElements(env, arr, a, 0);
}

 

案例七:在C中访问构造函数并构造对象

import java.util.Random;public class Test
{static{System.loadLibrary("Test");}public static native int  nextInt();public static void main(String[] args){System.out.println(nextInt());}
}

 

在C代码中调用Random类的构造方法构造一个Random实例,然后调用nextInt实例方法。

#include <stdio.h>
#include "Test.h"JNIEXPORT jint JNICALL Java_Test_nextInt(JNIEnv* env, jclass jc)
{/* 获得 Random 类, 注意表示类的字符串 */jclass class_Random = (*env)->FindClass(env, "java/util/Random");/* 获得 Random 构造器 方法id, "<init>"代表构造方法 */jmethodID id_Random = (*env)->GetMethodID(env, class_Random, "<init>", "()V");/* 构造一个Random类型的对象 */jobject obj_random = (*env)->NewObject(env, class_Random, id_Random, NULL);/* 下面调用这个对象的 nextInt 方法 */jmethodID id_nextInt = (*env)->GetMethodID(env, class_Random, "nextInt", "()I");jint ret = (*env)->CallIntMethod(env, obj_random, id_nextInt, NULL);return ret;
}

 

 

 案例八: 在本地方法中处理异常

public class Test
{static{System.loadLibrary("Test");}/*这里的luckyNumber方法纯粹测试目的:当name为zhangsan时一定会抛出一个IllegalArgumentException异常当name为lisi时,会调用Random.next(-10)主动抛出一个IllegalArgumentException异常,但是可以使用第二个参数来决定是否要抛出到 jvm 当name为其他值时,无异常 */public static native int  luckyNumber(String name, boolean nativeHandleException);public static void main(String[] args){System.out.println(Test.luckyNumber("zhangsan", false));}
}

 

C代码:

#include <stdio.h>
#include <string.h>
#include "Test.h"JNIEXPORT jint JNICALL Java_Test_luckyNumber(JNIEnv* env, jclass jc, jstring name, jboolean nativeHandleException)
{const char* cname;cname = (*env)->GetStringUTFChars(env, name, NULL);/* 当name为zhangsan时我们主动抛出一个异常 */    if(strcmp(cname, "zhangsan") == 0){jclass class_Exception = (*env)->FindClass(env, "java/lang/IllegalArgumentException");/* 主动抛出异常 */(*env)->ThrowNew(env, class_Exception, "zhangsan is a bad guy, he can't be given a lucky number");/* 本地方法抛出异常后并不会主动终止,所以要手动return */return;}    /* 调用Random.nextInt 产生一个随机幸运数 */jclass class_Random = (*env)->FindClass(env, "java/util/Random");jmethodID id_Random = (*env)->GetMethodID(env, class_Random, "<init>", "()V");jobject obj_random = (*env)->NewObject(env, class_Random, id_Random, NULL);jmethodID id_nextInt = (*env)->GetMethodID(env, class_Random, "nextInt", "(I)I");jint ret;/* 当name为lisi时,我们使用负数来作为nextInt的参数,从而让他抛出一个异常  */if(strcmp(cname, "lisi") == 0){ret = (*env)->CallIntMethod(env, obj_random, id_nextInt, (-10) );/*检查是否有异常挂起 */jboolean hasException = (*env)->ExceptionCheck(env);/*当有异常挂起并且要求在native中主动处理异常时,主动clear,这样就不会通知 虚拟机 了*/if(hasException && nativeHandleException){    /* 主动清除挂起的异常 */(*env)->ExceptionClear(env);        printf("the exception is handled in native function/n");}else if(hasException){return;}}else{ret = (*env)->CallIntMethod(env, obj_random, id_nextInt, 10);}    return ret;
}

 

转载于:https://www.cnblogs.com/zh1164/p/6283831.html

http://www.lbrq.cn/news/1116919.html

相关文章:

  • 新闻网站建设条件/seo站长工具查询
  • 音乐网站开发 群/在百度上怎么发布信息
  • 专门做企业名录的网站/信阳seo公司
  • 网站做实名认证/专业北京网站建设公司
  • 网站建设平台流程/seo推广方案怎么做
  • 模板网站robots怎么做/太原百度推广开户
  • 电子政务政府门户网站建设方案/廊坊关键词排名首页
  • wordpress 多域名绑定/北京seo优化诊断
  • wordpress收费下载/成都网站快速优化排名
  • wordpress主机 seo/宁波 seo整体优化
  • 建设网站服务器/百度一下你就知道了 官网
  • 斗鱼网站的实时视频是怎么做的/百度最新收录方法
  • 建设银行个人官方网站/推广普通话手抄报内容资料
  • 大连市城市建设投资集团网站/培训心得总结怎么写
  • 麒贺丝网做的网站优化/搜索引擎营销的简称是
  • 中国水土保持与生态环境建设网站/网络信息发布平台
  • 做外贸网站需要注意些什么/宁德市教育局
  • html5电影网站建设/seo兼职工资一般多少
  • 哪个yy频道做天龙私服网站/制作一个简单的html网页
  • 网站搭建好有什么内容可以修改/广告竞价推广
  • 上海建设手机网站/百度推广教程视频教程
  • 青岛高端网站开发公司/武汉seo推广优化公司
  • 云南旅行社网站建设/微信群拉人的营销方法
  • 无锡seo网站推广/seo权威入门教程
  • 深圳微商城网站制作/西安网站建设哪家好
  • 网站建设流程总结/服装品牌策划方案
  • 找生意做去哪个网站/佛山seo教程
  • 个人中心页面/推广排名seo
  • 如何设置网站图标favicon.ico/镇江网站制作公司
  • 商业地产网站建设/石家庄网站优化
  • 音视频同步技术初剖析:原理、实现与FFmpeg分析
  • MybatisPlus由浅入深
  • 【SpringBoot】实战-开发模式及环境搭建
  • GBase 8a 与 Spring Boot + MyBatis 整合实战:从环境搭建到CRUD操作
  • Kafka与Flink打造流式数据采集方案:以二手房信息为例
  • MIPI DSI(四) video 和 command 模式