JAVA 如何 调用 C++的lib

zoldean 发布于 2015/02/03 00:20
阅读 6K+
收藏 2

最近做项目,使用java进行开发,需要调用第三方提供的LIB文件。

手头有的资源是

还有

问题如下:

1)在java 平台上是不是只能调用DLL文件?

    我用JNA的方法,发现如果是LIB的话,eclipse会报错找不到文件,改成DLL会报其他错误,但是似乎文件能     找到。

    代码如下(自己编译了一个超简单的LIB,仅做测试)

package com.iscas;

import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;

public class CallLib
{
	public interface TestJNA extends StdCallLibrary  {		
		TestJNA INSTANCE = (TestJNA)Native.loadLibrary("hello",TestJNA.class);
		public int add(int a, int b);	
		public boolean print(String s);
	}
	
	public static void main(String[] args) 
	{  
        System.out.println(TestJNA.INSTANCE.add(3, 4));  
        System.out.println(TestJNA.INSTANCE.print("FUCK"));
    }  

}



    报出错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'hello': Native library (win32-x86-64/hello.dll) not found in resource path ([file:/E:/workplace/CallLib/bin/, file:/E:/workplace/CallLib/jna-4.1.0.jar])
	at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:271)
	at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
	at com.sun.jna.Library$Handler.<init>(Library.java:147)
	at com.sun.jna.Native.loadLibrary(Native.java:412)
	at com.sun.jna.Native.loadLibrary(Native.java:391)
	at com.iscas.CallLib$TestJNA.<clinit>(CallLib.java:15)
	at com.iscas.CallLib.main(CallLib.java:22)



2)将上个问题的LIB改成DLL,不会报出找不到文件,但是会报错误“不是有效的win 32程序”

    那么,如果使用JAVA调用DLL的时候,是不是需要JDK,ECLIPSE,DLL位数都是32位?

    将自己写的那个超简单的LIB重新编译为DLL,报错如下:

    

Exception in thread "main" java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序。

	at com.sun.jna.Native.open(Native Method)
	at com.sun.jna.Native.open(Native.java:1759)
	at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:260)
	at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
	at com.sun.jna.Library$Handler.<init>(Library.java:147)
	at com.sun.jna.Native.loadLibrary(Native.java:412)
	at com.sun.jna.Native.loadLibrary(Native.java:391)
	at com.iscas.CallLib$TestJNA.<clinit>(CallLib.java:9)
	at com.iscas.CallLib.main(CallLib.java:16)

    我的环境是WIN 8 64位,eclipse 64位, JDK64位,DLL是win8下VS 2010编译的

综上:

在我现有的资源的下(头文件 和 LIB),我怎么才能用java 调用这两个LIB文件呢?

而且我并不知道LIB里面的函数和参数都是什么。。。。



加载中
0
m
magiclogy
虽然不会java,但是你明显做了蠢事:直接改文件拓展名。

你去zlib的主站去下载动态库,拓展名是dll的:http://zlib.net/zlib128-dll.zip

m
magiclogy
回复 @zoldean : zlib很著名,所以很可能就是相同的东西,你看看头文件里的版权信息吧。当然,也可能是定制版,那你直接找第三方要dll,或者基于这个lib,用C做一个dll吧。
zoldean
zoldean
这个 ZLIB是第三方提供的定制化的LIB,做数据压缩和解压缩的,不知道下载的那个和这个是不是一样。。。
0
甘薯
甘薯

没用过JNA, 但是很明显, lib文件是不能被java直接使用的, lib是c/c++的编译库文件, 不是二进制可执行的dll或者so. 你根本就不能把它强行改名改成一个dll, 这是一个新手都不应该犯的错误!

回答你的问题,

1.是的

2.和是不是32位无关, windows自己应该能处理好兼容性的问题, 你的错误在于你改名之后lib并不能变成真正的dll.

你如果自己编写编译出来的dll也有问题, 发代码上来看一下, 有时候虽然生成了dll并不代表编译连接成功了.本地原生代码的开发比java的情况要复杂.

你如果不愿意直接下载网站上的dll, 可以自己通过引入lib文件来生成dll.


甘薯
甘薯
你必须选择的时候就选择创建library。你选择的console其实是dos窗口运行的exe
zoldean
zoldean
回复 @甘薯 : 这个,我确实很水恩,我是创建了一个 win32控制台,选择空项目,然后编译的时候把项目配置改为DLL/LIB的,这样难道也不行麽?
甘薯
甘薯
回复 @zoldean : 看来你对windows开发是一无所知啊... 你创建工程的时候就要选择生成一个library而不是exe. 如果你选择exe生成好之后你改名成dll肯定是不行的...
zoldean
zoldean
谢谢您,我自己写的DLL就是个helloWord 的程序, 编译的时候把配置从生成EXE文件 改为生成 DLL,之后在java 调用DLL的时候就报出“不是有效的XXX”。。。 手头没有DLL,只有他们给的LIB文件,所以很蛋疼。。。
0
二的基本算合格
二的基本算合格

1)在java 平台上是不是只能调用DLL文件?
不是
Java使用JNI调用Windows和Linux系统上的C/C++库都可以,就是说dll和so在各自系统上都可以调用。

2)将上个问题的LIB改成DLL,不会报出找不到文件,但是会报错误“不是有效的win 32程序”

重命名的方法?!把你的c/c++源码和编译过程写出来,十有八九是你编译或者环境的问题。

有头文件一般就知道so里面的函数定义了~~

zoldean
zoldean
回复 @二的基本算合格 : 额 我的意思是 java 是不是只能调用动态链接库,即DLL或者SO,能不能调用静态链接库如LIB,然后。。。我现在是觉得不能的
二的基本算合格
二的基本算合格
回复 @甘薯 : 在头文件中写函数声明是一个普通情况下的做法,有了函数的声明和对应平台的动态库,使用JNA的程序一般就可以调用动态库完成java程序中调用c/c++动态库函数操作,一般的操作都是这样的,为第三方做的时候,对方也只会提供头文件,而具体实现都是商业私密,按照头文件就可以使用JNA开发,这算一个比较正常的流程~
二的基本算合格
二的基本算合格
回复 @甘薯 : 额,楼主的问题是是java平台是不是只能调用dll文件?答案当然不是,dll和so是不同平台的动态库,java均可调用,但是说java只能调用dll就是错的,比如:苹果是水果是对的,但是水果是苹果就是不对的。
甘薯
甘薯
这个回答... 1.在windows平台是dll, 在unix/linux当然就是so了... 但是这些东西的性质都一样都是动态链接库, 所以只能调用dll的说法是对的.因为dll就是动态链接库. 2.头文件是说lib中或者so, dll, 甚至静态链接库中定义了那些函数...
0
loki_lan
loki_lan
Jacob可以调用COM+接口,试试吧。
0
南湖船老大
南湖船老大
楼主搜下 lib 和 dll 的差别,印象就深刻了
0
Monkey
Monkey
jna不能直接调用c++的dll,除非你暴露出c的接口。jna是可以直接调用c的动态库的,只要注意好数据对象的mapping就可以了。自己看先去看看jna官方文档,实际上jna只是jni的封装。
返回顶部
顶部