java静态库(java静态类怎么写)
华为云服务器特价优惠火热进行中! 2核2G2兆仅需 38 元;4核4G3兆仅需 79 元。购买时间越长越优惠!更多配置及优惠价格请咨询客服。
合作流程: |
本篇文章给大家谈谈java静态库,以及java静态类怎么写对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
微信号:cloud7591如需了解更多,欢迎添加客服微信咨询。
复制微信号
本文目录一览:
- 1、java如何使用静态库
- 2、Android中静态库和共享库的区别
- 3、Android.mk介绍(一)
- 4、java 如何调用一个已经存在的静态库,并输入和获取参数! 例如:静态库中已经存在函数 ret=ys_tpcall(aa);
- 5、android中java静态库和java共享库有什么区别?
- 6、Java的“静态库链接”
java如何使用静态库
1.缺少declare,正确的描述如下
private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
2 declare的说明
Declare 语句
用于在模块级别中声明对动态链接库 (DLL) 中外部过程的引用。
语法 1
[Public | Private] DeclareSubnameLib"libname" [Alias"aliasname"] [([arglist])]
语法 2
[Public | Private] DeclareFunctionnameLib"libname" [Alias"aliasname"] [([arglist])] [Astype]
Declare 语句的语法包含下面部分:
部分 描述
Public 可选的。用于声明对所有模块中的所有其它过程都可以使用的过程。
Private 可选的。用于声明只能在包含该声明的模块中使用的过程。
Sub 可选的(但Sub 或 Function 二者需选其一)。表示该过程没有返回值。
Function 可选的(但Sub 或 Function 二者需选其一)。表示该过程会返回一个可用于表达式的值。
name 必需的。任何合法的过程名。注意动态链接库的入口处(entry points)区分大小写。
Lib 必需的。指明包含所声明过程的动态链接库或代码资源。所有声明都需要Lib 子句。
libname 必需的。包含所声明的过程动态链接库名或代码资源名。
Alias 可选的。表示将被调用的过程在动态链接库 (DLL)
中还有另外的名称。当外部过程名与某个关键字重名时,就可以使用这个参数。当动态链接库的过程与同一范围内的公用变量、常数或任何其它过程的名称相同时,也可以使用
Alias。如果该动态链接库过程中的某个字符不符合动态链接库的命名约定时,也可以使用 Alias。
aliasname 可选的。动态链接库或代码资源中的过程名。如果首字符不是数字符号 (#),则
aliasname 是动态链接库中该过程的入口处的名称。如果首字符是
(#),则随后的字符必须指定该过程的入口处的顺序号。
arglist 可选的。代表调用该过程时需要传递的参数的变量表。
type 可选的。Function 过程返回值的数据类型;可以是 Byte、布尔、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(只支持变长)或 Variant,用户定义类型,或对象类型。
arglist 参数的语法以及语法各个部分如下:
[Optional] [ByVal | ByRef] [ParamArray] varname[( )] [Astype]
Android中静态库和共享库的区别
简单来讲:
静态库是在连接阶段直接拷贝到代码中使用的,而共享库是由加载器加载到内存,在运行时使用的。
编译出来的静态库(这里指jar包)里每个java文件对应的class文件都单独存在,可以直接导入Eclipse等IDE使用
而编译出来的共享库(jar包),内部是Android字节码Dex格式的文件,一般无法导入Eclipse等IDE使用。Android.mk中由BUILD_JAVA_LIBRARY指定生成共享BUILD_STATIC_JAVA_LIBRARY指定生成静态库。
Android.mk介绍(一)
在Linux下,可以通过Makefile来对源码工程进行管理,Android.mk文件是Makefile的一小部分,它用来对Android程序进行编译。Android.mk文件中描述了哪些C文件将被编译且指明了如何编译。Android.mk文件用来告知NDK Build 系统关于Source的信息。
1、编译可执行程序
2、编译动态库或静态库
3、预编译文件(APK或Java库)
以上三种是Android.mk的主要用法,我们写mk文件时也就是以上三种目的。
首先看一个最简单的Android.mk的例子:
讲解:
每个Android.mk文件必须以定义 LOCAL_PATH 为开始。它用于在开发tree中查找源文件。
宏 my-dir 由Build System提供。返回包含Android.mk的目录路径。
CLEAR_VARS 变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx.
例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理 LOCAL_PATH .
这个清理动作是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。
LOCAL_MODULE 模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。
Build System会自动添加适当的前缀和后缀。例如,foo,要产生动态库,则生成libfoo.so.
但请注意:如果模块名被定为:libfoo.则生成libfoo.so. 不再加前缀。
LOCAL_SRC_FILES变量必须包含将要打包如模块的C/C++ 源码。
不必列出头文件,build System 会自动帮我们找出依赖文件。
缺省的C++源码的扩展名为.cpp. 也可以修改,通过LOCAL_CPP_EXTENSION。
BUILD_SHARED_LIBRARY:是Build System提供的一个变量,指向一个GNU Makefile Script。
它负责收集自从上次调用include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定编译为什么。
BUILD_STATIC_LIBRARY:编译为静态库。
BUILD_SHARED_LIBRARY :编译为动态库
BUILD_EXECUTABLE:编译为Native C可执行程序
BUILD_PACKAGE(既可以编apk,也可以编资源包文件,但是需要指定LOCAL_EXPORT_PACKAGE_RESOURCES:=true)
BUILD_JAVA_LIBRARY(Java共享库)
BUILD_STATIC_JAVA_LIBRARY(java静态库)
Android源码中有大量的mk文件,Android系统的编译就是靠着这些mk文件的,所以学好是非常有必要的哦!
java 如何调用一个已经存在的静态库,并输入和获取参数! 例如:静态库中已经存在函数 ret=ys_tpcall(aa);
给出一个windows下dll的实例。linux下.a的静态库只是头文件和编译有所不同,另外需要将编译后的动态库文件放入/usr/lib下,使用ldconfig载入。
一 先制作一个系统中有的DLL文件(cpp给出的sdk接口)
既然是测试我们就把我们这个dll叫做testDll吧,为了简单其间,我只写一个add方法,就是简单的2个数字相加,对于真正的开发中我们肯定会遇到其他类型,java到c/cpp中类型需要转换,具体类型转换对应关系g一下就能得到,我也不在列举。c/cpp中一个class一般包含2个文件,一个头文件定义(*.h),一个文件主体(*.c/*.cpp)。啰嗦了这么多还是直接动手吧,先在vs2008中建立一个工程(当然你也可以直接编写不用这些IDE工具,gcc g++的命令自己g。下同,不在注释不在废话),选取win32工程
键入工程名字testDll,点击next选取DLL,然后点击完成
打开我们的testdll.cpp,添加进我们的add方法
C++代码
1.int add(int a,int b){
2. return a+b;
3.}
int add(int a,int b){
return a+b;
}
注意到文件列表里并没有testDll.h,因为我们要给出调用者一个接口,如果不给头文件,人家就没办法调用,所以我们就必须添加一个头文件testDll.h。
C++代码
1.#ifdef TEST_DLL
2.#define TEST_API __declspec(dllexport)
3.#else
4.#define TEST_API __declspec(dllimport)
5.#endif
6.
7./* Set up for C function definitions, even when using C++ */
8.#ifdef __cplusplus
9.extern "C" {
10.#endif
11.
12.TEST_API int add(int,int);
13.
14./* Ends C function definitions when using C++ */
15.#ifdef __cplusplus
16.}
17.#endif
#ifdef TEST_DLL
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
TEST_API int add(int,int);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
在这个头文件中我们把我们的add方法给定义了进去。注意到testdll.cpp中#include "stdafx.h",所以我们就把这个testDll.h include进stdafx.h里面。
按道理说我们的这个dll已经完成了,但是一般c/cpp给接口SDK的时候大都给.h和.lib,为了一步生成dll和lib,我们添加进一个testDll.def,有了这个文件就可以一步生成dll和lib。在source file里右键add new item ,选择Module-Definition File
键入testDll,OK了,我们可以直接build了。生成testDll.dll和testDll.lib。
把testDll.dll扔到system32目录里等待我们高大威猛的java jni调用。
二 JNI
2.1 编写java文件
为了显示我们的与众相同,我们就把我们的这个java文件命名为Demo.java顺便直接带上包名
,因为我们知道人家给我们的接口里有个add方法,所以我们就直接来个调用吧。
Java代码
1.package com.testJni.testDemo;
2.
3.public class Demo {
4. static
5. {
6. //System.out.println(System.getProperty("java.library.path"));
7. System.loadLibrary("testDll");
8. System.loadLibrary("jniDll");
9. }
10. public native static int add(int a,int b);
11.
12.}
package com.testJni.testDemo;
public class Demo {
static
{
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("testDll");
System.loadLibrary("jniDll");
}
public native static int add(int a,int b);
}
demo.java代码暂时如此,我们把将要生成的jni的dll叫做jniDll,有童鞋讲,我不想用你这个烂名字jniDll多俗啊,没关系,你可以换,随你换,生成文件后你再换也可以,现在换也可以。
2.2 生成.h头文件
javah命令,不多讲。生成的文件com_testJni_testDemo_Demo.h这个文件的命名规则我就不多讲了,一目了然。
C++代码
1./* DO NOT EDIT THIS FILE - it is machine generated */
2.#include jni.h
3./* Header for class com_testJni_testDemo_Demo */
4.
5.#ifndef _Included_com_testJni_testDemo_Demo
6.#define _Included_com_testJni_testDemo_Demo
7.#ifdef __cplusplus
8.extern "C" {
9.#endif
10./*
11. * Class: com_testJni_testDemo_Demo
12. * Method: add
13. * Signature: (II)I
14. */
15.JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
16. (JNIEnv *, jclass, jint, jint);
17.
18.#ifdef __cplusplus
19.}
20.#endif
21.#endif
/* DO NOT EDIT THIS FILE - it is machine generated */
#include jni.h
/* Header for class com_testJni_testDemo_Demo */
#ifndef _Included_com_testJni_testDemo_Demo
#define _Included_com_testJni_testDemo_Demo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_testJni_testDemo_Demo
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
2.3 用c/cpp实现这个头文件
c/cpp中已经实现了这个add方法,我们只需要调用就可以啦。所以直接vs2008中建立一个dll工程,工程名我们就叫jniDll,具体过程不再多讲,方法同上面testDll的建立一样。在这个工程里kimmking把需要引用的包、文件等已经讲的很清楚了。打开jniDll.cpp,添加下面代码
C++代码
1.JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
2.(JNIEnv *env,jclass jobject,jint a,jint b){
3.
4. return add(a,b);
5.}
JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
(JNIEnv *env,jclass jobject,jint a,jint b){
return add(a,b);
}因为int对应的类型就刚好是jint,所以就不需要转换,其他需要转换的类型自己g对应关系转换,注意释放。
这个工程里我们还需要打开 stdafx.h添加
C++代码
1.#include jni.h
2.
3.#include "testDll.h"
4.#include "com_testJni_testDemo_Demo.h"
#include jni.h
#include "testDll.h"
#include "com_testJni_testDemo_Demo.h"
在编译这个jniDll工程的时候需要引入testDll.h,com_testJni_testDemo_Demo.h,另外添加testDll.lib这个依赖。
好了做好这些后,build下,生成了我们期待已久的jniDll.dll,把这个dll同样扔到system32下。
三 测试
本人特懒,不想写多余的class,所以直接修改Demo.java 这也是刚才为什么讲暂时如此的原因
Java代码
1.package com.testJni.testDemo;
2.
3.public class Demo {
4. static
5. {
6. //System.out.println(System.getProperty("java.library.path"));
7. System.loadLibrary("testDll");
8. System.loadLibrary("jniDll");
9. }
10. public native static int add(int a,int b);
11. public static void main(String[] args) {
12. System.out.println(add(7,2));
13. }
14.}
package com.testJni.testDemo;
public class Demo {
static
{
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("testDll");
System.loadLibrary("jniDll");
}
public native static int add(int a,int b);
public static void main(String[] args) {
System.out.println(add(7,2));
}
}
四 最后补充
如果系统已经加载过c/cpp的dll,我们就不用再System.loadLibrary("testDll")了,加载一遍就可以了,因为我们刚才写的testDll系统没有加载,所以我就加载了一下。对于多个dll可以写多个System.loadLibrary去加载,修改static{}里面的内容不需要重新生成dll,除非你多加了一个调用方法,如果你看清楚规则,就不用javah命令就可以直接编写头文件,用javah太麻烦了。
android中java静态库和java共享库有什么区别?
程序编制一般需经编辑、编译、链接、加载和运行几个步骤。在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中。这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。
为了克服这个缺点可以采用动态链接库。这个时候链接器仅仅是在可执行文件中打上标志,说明需要使用哪些动态连接库;当运行程序时,加载器根据这些标志把所需的动态链接库加载到内存。
另外在当前的编程环境中,一般都提供方法让程序在运行的时候把某个特定的动态连接库加载并运行,也可以将其卸载(例如Win32的LoadLibrary()FreeLibrary()和Posix的dlopen()dlclose())。这个功能被广泛地用于在程序运行时刻更新某些功能模块或者是程序外观。
与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。通常class文件仅在需要使用时才加载。 这本身就是一种动态链接。
Java作为一种天生的动态链接语言,无法支持静态链接。但C语言的静态库除了静态链接的概念外,还隐含了一层意思,即库中的代码会打包到可执行文件中。JAVA中的JAR某种程度上类似一个可执行文件或库,借用C语言中静态库和动态库的概念,这里把最终会合并到生成的JAR文件中的JAR包叫静态库,反之仅仅在编译中使用,并不打包到生成的JAR包中,运行时需系统自行提供的JAR包叫动态库。
C的静态链接只把需要的代码复制过来,而Java用类似Fat Jar的方法,把所有的依赖库打包到最后的库中,眉毛胡子一把抓。这个问题可以用ProGuard解决,用它自己的话说是 It detects and removes unused classes, fields, methods, and attributes。
Eclipse中对JAR包的使用方式有两种,library和user libraries,其中library在工程中通过add jars...或add external jars...添加,出现在Referenced Libraries中,而user libraries需要在工作空间中管理,再在工程中通过add library...添加。这两种使用方式本身并没有静态库和动态库的区别,需要在打包或部署时再行指定。但user libraries的方式明显更方便管理多个工程共同使用的多个库,而系统库往往都有这种特性。
android的apk比JAR更类似可执行程序,而且因为标准库隐藏了很多功能,我们常常需要使用自己构建的系统库来编译。但android的ADT工具并没有提供是否将library或user libraries打包的选项。根据我的经验,ADT默认将library打包到apk中,而user libraries则仅用于编译,运行时再请求系统加载相关类。哪位同学有更明确的信息,还望指教,我短期内恐怕不会有时间去研究这个问题。
因此,可以这么说,在android中,library用来添加静态库,而user libraries用来管理动态库。千万不能弄错了,如果把静态库错误地加入动态库,运行时会出现找不到对应的class的错误,但因为Java语言的动态链接机制,只有运行到库中代码时才会出错;反之,如果把动态库做成了静态库,问题就更隐蔽了,可能只是dex文件特别大,而没有其它问题,也可能因加载了错误版本的系统代码,出现一些稀奇古怪的问题。慎之,慎之...
附:向eclispe中添加user Libraries的步骤:
1。点击eclipse的window菜单,选择“Preference”
2。在preferences窗口中选择java-User Libraries,然后点击窗口右边的New...按钮,在弹出的子窗口中输入user library的名称,此时在user libraries窗口中会出现新加的library名称。
3。向该user library中添加jar包。选中my_lib,然后点击Add JARS...按钮,选择你要添加的jar后,点击“打开”按钮,则my_lib库中就会出现你刚添加的jar文件信息。
4。最后点击窗口下的“OK”按钮,完成user library的添加和其jar的添加。
Java的“静态库链接”
Java的库组织方式就是 动态链接 的 从一个Java的jar包运行有可能要接一堆classpath就知道 和基于静态链接的C语言要实现动态链接要做额外的事情相似 Java要想实现类似C的静态链接也要做很多额外的事
用类似Fat Jar的方法 把所有的依赖库打包的最后的库中 其实不是静态链接——C的静态链接只把需要的代码复制过来 不是眉毛胡子一把抓 按说 以Java的思想 静态链接不是很必要 因此也就没有原生支持 但实践和理论毕竟差距很远 不是每个库都是标准库 假设你从别人的库中引用了几个类 为了支持你的程序 你必须提供别人的库(假设这个库并不流行) 再假设你自己写了一个库 以后再开发类似的程序就从库中派生 当然你不想把所有的代码都发行出去 这个问题在Netbeans上更为明显 Netbeans提供了一个swing框架 用起来当然很方便 但是当发行程序的时候你就会发现 Netbeans很负责任的把依赖库放到发行目录的lib下 居然有将近 M (禁掉粗口) 光写一个窗口就要 M!
ProGuard不光是个混淆器 它也能解决静态链接的问题 用它自己的话说是 It detects and removes unused classes fields methods and attributes 下面给出的是在Netbeans中用的Ant脚本 修改项目的build xml 添加
target name= post jar taskdef resource= proguard/ant/task properties classpath= ${libs proguard classpath} / copyfile src= ${dist jar} dest= ${dist dir}/pre jar / proguard warn= false obfuscate= false libraryjar path= ${java home}/lib/rt jar / injar path= ${javac classpath} filter= !META INF/MANIFEST MF / injar path= ${dist dir}/pre jar / outjar path= ${dist jar} / keep name= ${main class} method name= main / /keep keep name= jdesktop bean *** inding ext BeanAdapterProvider / keepclasseswithmembernames method name= getServiceNames / /keepclasseswithmembernames keepclasseswithmembernames method name= addPropertyChangeListener / /keepclasseswithmembernames /proguard /target
lishixinzhi/Article/program/Java/hx/201311/26546

java静态库的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java静态类怎么写、java静态库的信息别忘了在本站进行查找喔。
