当前位置: 首页 > 编程日记 > 正文

转 java c++互传arraylist

Java JNI由浅入深(包括:Java和C++互传ArrayList泛型对象参数)

 1694人阅读 评论(1) 收藏 举报

我们知道Java是一个运行在虚拟机里面的高级的编程语言,如果要调用系统的动态链接库的话,就要先声明native修饰的方法(类似接口里面的方法),再由C/C++程序来实现(类似实现接口里的方法)。这样Java调用这些native方法就相当于调用了C/C++里面实现了的方法。通常我们把这种机制叫做JNI(Java NativeInterfac),即Java 本地编程接口


          Android也同理,要学会在Android上进行NDK开发,首先我们到打好java JNI的基础。现在我们暂时把Android开发丢到一边先,试试在Java之下编译一个C动态链接库,再用Java程序调用。

1)先来个最简单的打印HelloWorld例子:

Java代码(HelloJni.java):

[java] view plaincopy
  1. import java.util.*;
  2. public class HelloJni{
  3. static{
  4. System.loadLibrary("hello");
  5. }
  6. public native static void sayHello();
  7. public static void main(String [] args)
  8. {
  9. HelloJni.sayHello();
  10. }
  11. }

生成头文件(HelloJni.h):

先javac HelloJni.java编译你的Java源码,再javah–jni HelloJni生成所需的头文件

头文件内容是这样的:

[java] view plaincopy
  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class HelloJni */
  4. #ifndef _Included_HelloJni
  5. #define _Included_HelloJni
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);
  10. #ifdef __cplusplus
  11. }
  12. #endif
  13. #endif


实现头文件声明的方法(HelloJni.cpp)


[c-sharp] view plaincopy
  1. #include "HelloJni.h"
  2. JNIEXPORT void JNICALL Java_HelloJni_sayHello(JNIEnv *env, jclass cls)
  3. {
  4. printf("HelloWorld");
  5. }

编译命令: g++ -I$JAVA_HOME/include-I$JAVA_HOME/include/linux HelloJni.cpp -shared -o libhello.so

命令参数解析:-I 是指引入java虚拟机的库的路径,-shared 是指编译成动态链接库(共享库) –o 输出文件名(注意,在Linux平台下的动态链接库有一个命名格式:“lib+库名+.so”在java代码里面loadLibrary的时候不要加lib前缀和.so后缀)

由于我这里把这个动态链接库编译放在当前目录下,所以还要设置环境变量LD_LIBRARY_PATH=该so动态链接库所在的目录,才能正常运行

#############################+++华丽的分割线+++###########################

2)好了,可以打印HelloWorld出来后,我们再深入一点点,传入一个int的数,在C/C++代码里面加1后返回。

Java代码(HelloJni.java):

[java] view plaincopy
  1. public class HelloJni{
  2. static{
  3. System.loadLibrary("hello");
  4. }
  5. public static native void sayHello();
  6. public native int getInt();
  7. public native void setInt(int i);
  8. public static void main(String args[]){
  9. //      HelloJni.sayHello();
  10. HelloJni hello = new HelloJni();
  11. hello.setInt(2);
  12. System.out.println(hello.getInt());
  13. }
  14. }

生成头文件(HelloJni.h):

[c-sharp] view plaincopy
  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class HelloJni */
  4. #ifndef _Included_HelloJni
  5. #define _Included_HelloJni
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);
  10. JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);
  11. JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);
  12. #ifdef __cplusplus
  13. }
  14. #endif
  15. #endif

实现头文件声明的方法(HelloJni.cpp)

[java] view plaincopy
  1. #include "HelloJni.h"
  2. int i=1;
  3. JNIEXPORT void JNICALL Java_HelloJni_sayHello
  4. (JNIEnv *env, jclass cls){
  5. printf("HelloWorld/n");
  6. }
  7. JNIEXPORT jint JNICALL Java_HelloJni_getInt
  8. (JNIEnv *env, jobject thiz){
  9. return i;
  10. }
  11. JNIEXPORT void JNICALL Java_HelloJni_setInt
  12. (JNIEnv *env, jobject thiz,jint ji){
  13. i = ji+1;
  14. }

运行结果:打印2


3)只是传入简单的数据类型不爽,这次让C/C++生成个Java对象返回

Java代码:pojo实体类(User.java)

[c-sharp] view plaincopy
  1. public class User{
  2. private long id;
  3. private String userName;
  4. private boolean isMan;
  5. private int age;
  6. public User(){}
  7. public User(long id, String userName, boolean isMan, int age) {
  8. super();
  9. this.id = id;
  10. this.userName = userName;
  11. this.isMan = isMan;
  12. this.age = age;
  13. }
  14. public long getId() {
  15. return id;
  16. }
  17. public void setId(long id) {
  18. this.id = id;
  19. }
  20. public String getUserName() {
  21. return userName;
  22. }
  23. public void setUserName(String userName) {
  24. this.userName = userName;
  25. }
  26. public boolean isMan() {
  27. return isMan;
  28. }
  29. public void setMan(boolean isMan) {
  30. this.isMan = isMan;
  31. }
  32. public int getAge() {
  33. return age;
  34. }
  35. public void setAge(int age) {
  36. this.age = age;
  37. }
  38. }

Java代码(HelloJni.java):

[java] view plaincopy
  1. public class HelloJni{
  2. static{
  3. System.loadLibrary("userbean");
  4. }
  5. public static native void sayHello();
  6. public native int getInt();
  7. public native void setInt(int i);
  8. public native void setUser(String userName);
  9. public native User getUser();
  10. public static void main(String args[]){
  11. //      HelloJni.sayHello();
  12. HelloJni hello = new HelloJni();
  13. //      hello.setInt(2);
  14. //      System.out.println(hello.getInt());
  15. hello.setUser("LiangYaotian");
  16. User user = hello.getUser();
  17. System.out.println("user from c/c++");
  18. System.out.println("name:"+user.getUserName());
  19. System.out.println("isMan?:"+user.isMan());
  20. System.out.println("age:"+user.getAge());
  21. }
  22. }

生成头文件(HelloJni.h):

[c-sharp] view plaincopy
  1. #include <jni.h>
  2. /* Header for class HelloJni */
  3. #ifndef _Included_HelloJni
  4. #define _Included_HelloJni
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);
  9. JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);
  10. JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);
  11. JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *, jobject, jstring);
  12. JNIEXPORT jobject JNICALL Java_HelloJni_getUser  (JNIEnv *, jobject);
  13. #ifdef __cplusplus
  14. }
  15. #endif
  16. #endif

实现头文件声明的方法(HelloJni.cpp)

[c-sharp] view plaincopy
  1. #include <iostream>
  2. #include <stdio.h>
  3. using namespace std;
  4. int i=1;
  5. jobject user;
  6. JNIEXPORT void JNICALL Java_HelloJni_sayHello
  7. (JNIEnv *env, jclass cls){
  8. printf("HelloWorld/n");
  9. }
  10. JNIEXPORT jint JNICALL Java_HelloJni_getInt
  11. (JNIEnv *env, jobject thiz){
  12. return i;
  13. }
  14. JNIEXPORT void JNICALL Java_HelloJni_setInt
  15. (JNIEnv *env, jobject thiz,jint ji){
  16. i = ji+1;
  17. }
  18. JNIEXPORT void JNICALL Java_HelloJni_setUser
  19. (JNIEnv *env, jobject thiz, jstring name){
  20. jclass userClass = env->FindClass("User");
  21. jmethodID userMethod = env->GetMethodID(userClass,"<init>","()V");
  22. jfieldID mId = env->GetFieldID(userClass,"id","J");
  23. jfieldID mUserName = env->GetFieldID(userClass,"userName","Ljava/lang/String;");
  24. jfieldID mIsMan = env->GetFieldID(userClass,"isMan","Z");
  25. jfieldID mAge = env->GetFieldID(userClass,"age","I");
  26. jobject userObject = env->NewObject(userClass,userMethod);
  27. env->SetObjectField(userObject,mUserName,name);
  28. env->SetLongField(userObject,mId,1001);
  29. env->SetBooleanField(userObject,mIsMan,1);
  30. env->SetIntField(userObject,mAge,21);
  31. user = userObject;
  32. }

4)有些同学可能会说:“返回个Java对象算什么啊,C/C++和Java之间互传复杂对象才好玩呢!”正所谓“不怕做不到,就怕想不到”,我们接着重构一下上面那个例子!


这次我们传包含有User对象的List到C/C++程序里面


Java代码(User.java)

同上。

Java代码(HelloJni.java)

[java] view plaincopy
  1. import java.util.*;
  2. public class HelloJni{
  3. static{
  4. System.loadLibrary("userbean");
  5. }
  6. public native int get();
  7. public native void set(int i);
  8. public native void setUser(String userName);
  9. public native User getUser();
  10. public native void setUserList(ArrayList<User> userList);
  11. public native ArrayList<User> getUserList();
  12. public static void main(String [] args)
  13. {
  14. HelloJni hello = new HelloJni();
  15. //      hello.set(2);
  16. //      System.out.println(hello.get());
  17. /*
  18.                 hello.setUser("LiangYaotian");
  19.                 User user = hello.getUser();
  20.                 System.out.println("user from c/c++");
  21.                 System.out.println("name:"+user.getUserName());
  22.                 System.out.println("isMan?:"+user.isMan());
  23.                 System.out.println("age:"+user.getAge());
  24.         */
  25. ArrayList<User> userList = new ArrayList<User>();
  26. for(int i=0;i<10;i++){
  27. User u = new User((long)(1000+i),"LiangYaotian"+i,true,21);
  28. userList.add(u);
  29. }
  30. hello.setUserList(userList);
  31. userList = null;
  32. userList = hello.getUserList();
  33. System.out.println("ArrayList<User> construct from C++,then Java print it.....");
  34. for(User u : userList){
  35. System.out.println("id:"+u.getId()+"; name:"+u.getUserName());
  36. }
  37. }
  38. }

C头文件(HelloJni.h)

[java] view plaincopy
  1. #include <jni.h>
  2. /* Header for class HelloJni */
  3. #ifndef _Included_HelloJni
  4. #define _Included_HelloJni
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);
  9. JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);
  10. JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);
  11. JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *, jobject, jstring);
  12. JNIEXPORT jobject JNICALL Java_HelloJni_getUser  (JNIEnv *, jobject);

头文件的实现(HelloJni.cpp)

[java] view plaincopy
  1. #include "HelloJni.h"
  2. int i=1;
  3. jobject user;
  4. JNIEXPORT jint JNICALL Java_HelloJni_get
  5. (JNIEnv *env, jobject jthiz){
  6. printf("HelloWorld/n");
  7. }
  8. JNIEXPORT void JNICALL Java_HelloJni_set
  9. (JNIEnv *env, jobject jthiz, jint ji){
  10. i = ji+1;
  11. }
  12. JNIEXPORT void JNICALL Java_HelloJni_setUser
  13. (JNIEnv *env, jobject jthiz, jstring name){
  14. jclass userClass = env->FindClass("User");
  15. jmethodID userMethod = env->GetMethodID(userClass,"<init>","()V");
  16. jfieldID mId = env->GetFieldID(userClass,"id","J");
  17. jfieldID mUserName = env->GetFieldID(userClass,"userName","Ljava/lang/String;");
  18. jfieldID mIsMan = env->GetFieldID(userClass,"isMan","Z");
  19. jfieldID mAge = env->GetFieldID(userClass,"age","I");
  20. jobject userObject = env->NewObject(userClass,userMethod);
  21. env->SetObjectField(userObject,mUserName,name);
  22. env->SetLongField(userObject,mId,1001);
  23. env->SetBooleanField(userObject,mIsMan,1);
  24. env->SetIntField(userObject,mAge,21);
  25. user = userObject;
  26. }
  27. JNIEXPORT jobject JNICALL Java_HelloJni_getUser
  28. (JNIEnv *env, jobject jthiz){
  29. return user;
  30. }
  31. JNIEXPORT void JNICALL Java_HelloJni_setUserList
  32. (JNIEnv *env, jobject jthiz, jobject userList){
  33. int i;
  34. //class ArrayList
  35. jclass cls_arraylist = env->GetObjectClass(userList);
  36. //method in class ArrayList
  37. jmethodID arraylist_get = env->GetMethodID(cls_arraylist,"get","(I)Ljava/lang/Object;");
  38. jmethodID arraylist_size = env->GetMethodID(cls_arraylist,"size","()I");
  39. jint len = env->CallIntMethod(userList,arraylist_size);
  40. printf("get java ArrayList<User> object by C++ , then print it...../n");
  41. for(i=0;i<len;i++){
  42. jobject obj_user = env->CallObjectMethod(userList,arraylist_get,i);
  43. jclass cls_user = env->GetObjectClass(obj_user);
  44. jmethodID user_getId = env->GetMethodID(cls_user,"getId","()J");
  45. jmethodID user_getUserName = env->GetMethodID(cls_user,"getUserName","()Ljava/lang/String;");
  46. jmethodID user_isMan = env->GetMethodID(cls_user,"isMan","()Z");
  47. jmethodID user_getAge = env->GetMethodID(cls_user,"getAge","()I");
  48. jstring name = (jstring)env->CallObjectMethod(obj_user,user_getUserName);
  49. jboolean b = true;
  50. const char *namePtr = env->GetStringUTFChars(name,&b);
  51. jlong id = env->CallLongMethod(obj_user,user_getId);
  52. jboolean sex = env->CallBooleanMethod(obj_user,user_isMan);
  53. jint age = env->CallIntMethod(obj_user,user_getAge);
  54. printf("Id:%d; ",id);
  55. printf("Name:%s; ",namePtr);
  56. printf("isMan? %d; ",sex);
  57. printf("Age:%d /n ",age);
  58. }
  59. }
  60. JNIEXPORT jobject JNICALL Java_HelloJni_getUserList
  61. (JNIEnv *env, jobject jthiz){
  62. //ArrayList Object
  63. jclass cls_ArrayList = env->FindClass("java/util/ArrayList");
  64. jmethodID construct = env->GetMethodID(cls_ArrayList,"<init>","()V");
  65. jobject obj_ArrayList = env->NewObject(cls_ArrayList,construct,"");
  66. jmethodID arrayList_add = env->GetMethodID(cls_ArrayList,"add","(Ljava/lang/Object;)Z");
  67. //User Object
  68. jclass cls_user = env->FindClass("User");
  69. //none argument construct function
  70. jmethodID construct_user = env->GetMethodID(cls_user,"<init>","()V");
  71. //new a object
  72. jobject obj_user = env->NewObject(cls_user,construct_user,"");
  73. //get method id
  74. /*
  75.         jmethodID user_setId = env->GetMethodID(cls_user,"setId","(J)V");
  76.         jmethodID user_setUserName = env->GetMethodID(cls_user,"setUserName","(Ljava/lang/String;)V");
  77.         jmethodID user_setMan = env->GetMethodID(cls_user,"setMan","(Z)V");
  78.         jmethodID user_setAge = env->GetMethodID(cls_user,"setAge","(I)V");
  79.         */
  80. int i;
  81. for(i=0;i<10;i++){
  82. //new a object
  83. jobject obj_user = env->NewObject(cls_user,construct_user,"");
  84. //get field id
  85. jfieldID user_id = env->GetFieldID(cls_user,"id","J");
  86. jfieldID user_name = env->GetFieldID(cls_user,"userName","Ljava/lang/String;");
  87. jfieldID user_isMan = env->GetFieldID(cls_user,"isMan","Z");
  88. jfieldID user_age = env->GetFieldID(cls_user,"age","I");
  89. env->SetLongField(obj_user,user_id,i);
  90. env->SetObjectField(obj_user,user_name,env->NewStringUTF("LiangYaoTian"));
  91. env->SetBooleanField(obj_user,user_isMan,1);
  92. env->SetIntField(obj_user,user_age,21);
  93. env->CallObjectMethod(obj_ArrayList,arrayList_add,obj_user);
  94. }
  95. return obj_ArrayList;
  96. }

运行结果:

转载于:https://www.cnblogs.com/qinjunni/archive/2012/02/20/2359181.html

相关文章:

GoAccess安装及分析nginx实时日志

GoAccess是一个基于终端的快速日志分析器。其核心思想是实时快速分析和查看Web服务器统计信息&#xff0c;而无需使用您的浏览器&#xff08;如果您希望通过SSH快速分析访问日志&#xff0c;或者只是喜欢在终端中工作&#xff09;&#xff0c;终端输出是默认输出&#xff0c;但…

在写游戏时钟类时,应确保时钟的计算是以某个固定的CPU为标准的

在写游戏时钟类时&#xff0c;应确保时钟的计算是以某个固定的CPU为标准的。下面通过一个例子来阐述如何实现这一思想&#xff1a; // 记录特定进程的affinity maskunsigned long lProcessAffinityMask;// 记录系统的affinity maskunsigned long lSystemAffinityMask;::GetProc…

学习Spring Boot

Spring boot 是什么 ? 简单说, spring boot 是一个构建项目的工具, 一个脚手架. Spring boot 能干什么? spring boot 做非常少的配置就可以构建生产级别的单体应用. Spring boot 怎么干的? 下面让我们来用spring boot 做一个hello world. 环境准备, 需要保证你的机器上已经有…

Linux添加用户组和添加用户

1.用户组 添加组&#xff1a;groupadd 组名 [rootServer-n93yom ~]# groupadd dev [rootServer-n93yom ~]# cat /etc/group | grep dev dev:x:10011: [rootServer-n93yom ~]# 删除组&#xff1a;groupdel 组名 [rootServer-n93yom ~]# groupdel dev [rootServer-n93yom ~]# cat…

用javascript实现仿163的js广告向下挤压页面的效果

本次实现一个js小小特效&#xff0c;效果就是广告从页面的上方出来将基本页面挤压下去。 实现的思路是将两个div&#xff08;广告div1和div2&#xff09;。将div1的高度不断增加&#xff0c;增加的同时div2的y轴坐标变大&#xff0c;div1的高度增加多少相对应的y轴坐标加大多少…

【eclipse】快速调整eclipse背景和格式的方法

第一步 第二步 第三步 &#xff1a;选择相应的格式 效果如图

对做C#自定义控件的一点心得

近期在做DSOFramer这个控件&#xff0c;打算自己弄一个自定义控件来封装这个COM组件&#xff0c;中间遇到很多曲折&#xff0c;研究了一个星期&#xff0c;终于完成了 下面总结一下我做DSOFramer这个自定义控件的注意地方&#xff1a; 1、在创建一个Windows窗体控件库的时候&am…

numpy知识点

1、nonzero 对于一维数据来说&#xff0c;将返回符合条件的 下标 >>> b1 np.array([True, False, True, False]) >>> np.nonzero(b1)(array([0, 2]),)对于二维数据来说&#xff0c;将返回两维 元组&#xff0c; 第一维是符合条件的 x的索引&#xff0c;第二…

Excel导入异常Cannot get a text value from a numeric cell解决

POI操作Excel时偶尔会出现Cannot get a text value from a numeric cell的异常错误。 异常原因&#xff1a;Excel数据Cell有不同的类型&#xff0c;当我们试图从一个数字类型的Cell读取出一个字符串并写入数据库时&#xff0c;就会出现Cannot get a text value from a numeric …

【蓝桥java】递归基础之反向输出字符串

题目&#xff1a;输入一个字符串&#xff0c;要求将该字符串反向输出 代码实现&#xff1a; package xn.zzunit.recurrence;/*** 递归方法反向输出字符串* author tyrantForever**/ public class Project1 {public static void main(String[] args) {String testString "…

SQL Server中灾难时备份结尾日志(Tail of log)的两种方法

简介 在数据库数据文件因各种原因发生损坏时&#xff0c;如果日志文件没有损坏。可以通过备份结尾日志&#xff08;Tail of log)使得数据库可以恢复到灾难发生时的状态。 例如: 上图中。在DB_1中做了完整备份&#xff0c;在Log_1,Log_2处做了日志备份。在Log_2备份之后不久&…

C examples

最近在看David R. Hanson 的《C Interfaces and Implementations》&#xff0c;文中第一章提到了Literate Programming 作者举了一个例子&#xff1a; 功能&#xff1a;用于检测输入中相邻且相同的单词 #include<stdio.h> #include<math.h> #include<errno.h&g…

特征工程:特征生成,特征选择(三)

转自&#xff1a;https://blog.csdn.net/cymy001/article/details/79169862 特征生成 特征工程中引入的新特征&#xff0c;需要验证它确实能提高预测得准确度&#xff0c;而不是加入一个无用的特征增加算法运算的复杂度。 1. 时间戳处理 时间戳属性通常需要分离成多个维度比如年…

JAVA设计模式之不变模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述不变&#xff08;Immutable&#xff09;模式的&#xff1a; 一个对象的状态在对象被创建之后就不再变化&#xff0c;这就是所谓的不变模式。 不变模式的结构 不变模式可增强对象的强壮型(robustness)。不变模式允许多个对象共享…

【蓝桥java】递归基础之智力训练

题目&#xff1a; 匪警请拨110,即使手机欠费也可拨通&#xff01; 为了保障社会秩序&#xff0c;保护人民群众生命财产安全&#xff0c;警察叔叔需要与罪犯斗智斗勇&#xff0c;因而需要经常性地进行体力训练和智力训练&#xff01; 某批警察叔叔正在进行智力训练&#xff1a; …

EF-Entity Framework 相关技术点收集贴

不定期、偶尔、添加更新 在网络上看到或者自己开发过程中碰到的EF&#xff0d;Entity Framework相关技术点 本文地址:http://www.cnblogs.com/vnii/archive/2012/02/28/2371736.html 1.数据表字段有默认值&#xff0c;比如DateTime类型的字段CreateTime默认值为数据新增的时间g…

[翻译]LightRacer游戏架构

1.0版本的Light Racer架构可说的不多。仅有一个单一的Activity&#xff0c;进行按钮的处理&#xff0c;显示游戏相关数据和显示GameView。我将在另一篇文章中说明游戏的画面是如何工作的&#xff0c;但是现在我先声明一下的就是&#xff1a;在Android中&#xff0c;单个Activit…

case when里的like功能 ////// 截取(substr)

case when里的like功能 假如要用到case when又要用到like这样的功能&#xff0c;即如果字符串包含‘语文’就怎么怎么样&#xff0c;包含‘数学’就怎么怎么样&#xff0c;包含‘英语’就怎么怎么样&#xff0c;like是用于where中的&#xff0c;放在case when里面是无效的&…

在Asp.Net MVC中设定site路径所对应的默认action

设置路由的default的Controller和Action可以达到我们预期的效果&#xff0c;代码如下所示&#xff1a; public class RouteConfig {public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.MapRoute(n…

【蓝桥java】递归基础之输出连续数字

题目&#xff1a;使用递归方法输出连续的数字 代码实现&#xff1a; package xn.zzunit.recurrence;/*** 递归方法输出连续的数字* author tyrantForever**/ public class Project2 {public static void main(String[] args) {printNumber(2, 9);}public static void printNu…

慢慢学Linux驱动开发,第十章,GNU C的扩展

内核开发者使用的C语言涵盖了ISO C99标准和GNU C扩展特性。这里简单介绍一下GNU C的扩展特性。 1.内联&#xff08;inline&#xff09;函数 GNU的C编译器支持内联函数&#xff0c;也是C的一个特性之一。就是函数会在所调用的位置上展开&#xff0c;这样做虽然会导致代码量的增加…

vMA学习笔记之一:将vMA加入域

目的&#xff1a; 将vMA加入域的方法 操作步骤&#xff1a; 1、 开启vMA 2、 按住AltF2切换到虚拟终端界面&#xff0c;使用vi-admin用户登录 2 3、 已经登录进来了 4、 在进行加域操作之前&#xff0c;必须确保DNS配置正确&#xff08;在初始化安装的时候会提示你设置DNS&…

关于DWG文件转换成PDF

最近有这样一个需求&#xff0c;客户会提供DWG文件&#xff0c;因为DWG文件是不能直接在网页上显示的&#xff0c;所以必须对他做处理&#xff0c;要求是转换成PDF格式。我查了很久的资料&#xff0c;很多都是基于C#和.NET的方法&#xff0c;而且都是说的很模糊&#xff0c;不是…

剑指offer--day07

1.1 题目&#xff1a;反转链表&#xff1a;输入一个链表&#xff0c;反转链表后&#xff0c;输出新链表的表头。 1.2 思路&#xff1a;这道题&#xff0c;我们要做到的是反转链表&#xff0c;我们的思路是将前一个节点与后一个节点断开&#xff0c;然后让后一个节点指向前一个节…

【蓝桥java】递归基础之计算共多少种走法

计算从某个位置&#xff08;x,y&#xff09;走到&#xff08;0,0&#xff09; 一共多少种走法 代码实现&#xff1a; package xn.zzunit.recurrence;/*** 从某个位置&#xff08;x,y&#xff09;走到&#xff08;0,0&#xff09; 一共多少种走法* author tyrantForever**/ pub…

数据库设计的三大范式

为了建立冗余较小、结构合理的数据库&#xff0c;设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库&#xff0c;必须满足一定的范式。在实际开发中最为常见的设计范式有三个&#xf…

JS得到对应字段 的值。遍历

这个写法不是经典。我受感触是因为。我写很多代码&#xff0c;没去想过怎么样去节省我们的开发时间&#xff0c;应该去写一些通用性的代码。 而且。我也没有把C#代码优化的思想转到各个地方。像JS的代码。我就没去想过怎么去优化。 加油吧。 function getPageListSet(pageIndex…

微信小程序开发中如何实现侧边栏的滑动效果?

原文链接&#xff1a;https://mp.weixin.qq.com/s/7CM18izpZqf0oc0D75IGmQ1概述在手机应用的开发中侧边栏滑动是很常见的功能&#xff0c;当然在小程序中也不会例外&#xff0c;很多特效还没有成熟案例&#xff0c;只能原生重写&#xff0c;所以今天在网上为大家收集整理来几个…

采购审批专题总结--bob

一采购审批设置的一般步骤&#xff1a; 前置步骤 ①定义安全性控制 N&#xff1a;PO/设置/采购/单据类型 ②使用审批结构 N&#xff1a;PO/设置/组织/财务选项 ③安全层次结构选择 N&#xff1a;PO/设置/组织/采购选项 ④采购…