「java调用静态库」java调用静态方法会创建对象吗

博主:adminadmin 2023-03-19 06:28:08 357

今天给各位分享java调用静态库的知识,其中也会对java调用静态方法会创建对象吗进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

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太麻烦了。

java 调用静态方法和构造函数和静态块执行的先后顺序

java中首先是静态块先执行,静态方法,最后是构造函数。示例如下:

public class ExA {  

    static {  

        System.out.println("父类--静态代码块");  

    }  

  

    public ExA() {  

        System.out.println("父类--构造函数");  

    }  

  

    {  

        System.out.println("父类--非静态代码块");  

    }  

  

    public static void main(String[] args) {  

        new ExB();  

    }  

}  

  

class ExB extends ExA {  

    static {  

        System.out.println("子类--静态代码块");  

    }  

    {  

        System.out.println("子类--非静态代码块");  

    }  

  

    public ExB() {  

        System.out.println("子类--构造函数");  

    }  

}  

执行结果 

===== 

父类--静态代码块 

子类--静态代码块 

父类--非静态代码块 

父类--构造函数 

子类--非静态代码块 

子类--构造函数

ndk生成的so怎么在java调用

1. 自己写.c文件,然后生成so库

2. 引用别人的静态库,或者动态库来生成新的jni调用库。

我们先来看最简单的编写一个jni调用的so库,包含一个获取字符串的方法,通过这个列子,我们主要是了解怎么在android的工程中调用jni的库,以及要注意的问题。

第一步:首先我们来看下我们的工程的目录

jni目录是我们生成库的文件,里面包含了一个.mk编译文件以及一系列的.c文件

libs目录是我们编译jni目录下的mk文件动态生成的。

当我们写好了jni下面的库文件以后,在当前目录下执行ndk-build则会自动生成我们需要调用的.so库文件。

第二步: java里面怎么调用jni的库文件,我们先看代码

public class MainActivity extends Activity {

/* A native method that is implemented by the

* 'hello-jni' native library, which is packaged

* with this application.

*/

public native String stringFromJNI();

/* this is used to load the 'hello-jni' library on application

* startup. The library has already been unpacked into

* /data/data/com.example.HelloJni/lib/libhello-jni.so at

* installation time by the package manager.

*/

static {

System.loadLibrary("hello-jni");

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

String str = stringFromJNI();

System.out.println("*****str:" + str);

}

}

在java文件中要做到调用jni文件生成的so库,需要做到2步

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]

关于java调用静态库和java调用静态方法会创建对象吗的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。