㈠ java用JNA调用c/c++的dll接口时,怎么获取接口中的out参数,例如:
java通过jna调用c++/c的.dll/.so库接口
1。通过jni技术可以实现java调用so文件(这个自己实现了,以前的日志也有,并没有用jni来调用dll文件,原因是自己对这个不熟啊,不知道怎样生成dll文件。。。。)。
2.使用jni的时候会显得很繁琐,因为要有许多函数的声明要相同,jna技术就可以省却这一点,拿到一个现成的dll,只要知道函数声明,就可以直接调用了(用jna还未实验调用so文件)。
下面介绍一下jna调用dll的过程。
1.导入jna.jar包,这个就不说了,下载一个就可以了。
2.主要代码:
import com.sun.jna.Library;import com.sun.jna.Native;public interface Net extends Library { Net lib = (Net)Native.loadLibrary("NetDvr2", Net.class); int NETDVR_startup();}//调用public class TestJna { public static void main(String[] args) { System.out.println(Net.lib.NETDVR_startup()); }}NetDvr2.dll放在工程的根目录下边即可。
可能出现的错误:
java.lang.UnsatisfiedLinkError: Unable to load library 'NetDvr2': ???????¨
原因是NetDvr2.dll(或者NetDvr2.so)还依赖于其他几个dll(so)文件,把他们一起拷到该java工程的根目录就行了。
查看一个dll文件所依赖的dll文件可以用Depends.exe。
㈡ 用Java怎么调用C语言已经编写好的DLL
1. 编写范例文档 public class TestNative { private native static int Max(int a,int b); public static void main(String[] args) { System.out.println(Max(4,5)); } static { System.loadLibrary("VCdll"); } } 其中 LoadLibrary中的DLL文件名称可以随便定.只要做好的动态链接库改名成这个字符串就可以了.而native函数的来源就是该动态链接库. 2. 做好该步准备以后,用javac TestNative.java生成TestNative.class. 检验语法. 3. 语法检查通过以后,用javah TestNative生成TestNative.h的C++头文件. 4. 用VC++6.0创建dll文件: <1>msdev->new->project->win32 Dynamic-Link Library <2>Enter project name (e.g. VCdll) <3>choose "An empty DLL project"->finish <4>将3生成的TestNative.h和jdk下的jni.h和jni_md.h加入到工程中去 <5>Create a c++ file, implements the native method. as follows: //TestNative.cpp #include "TestNative.h" JNIEXPORT jint JNICALL Java_TestNative_Max (JNIEnv * a, jclass b, jint x, jint y) { return x > y ? x : y; } 备注: A 其中的jni.h通常在 jdk\include\ 可以先拷贝到VC安装目录下的include目录下.一劳永逸,以后可以方便使用JNI技术. B 全部的数据类型需要考虑Java和VC的接口问题.用jint jstring 等. C 函数名称和自动生成的.h文件中规定的一致.命名规则是: Java_使用类_方法名 6. 全编译一下VC++工程. 如果没有出错,则此时生成动态链接库成功. 把动态链接库VCdll.dll拷贝到TestNative.java所在的目录上. 7.运行java TestNative. OK :-)
参考资料: http://hi..com/dinguangx/blog/item/196560017e40e2031c95832f.html
㈢ java怎么引用c
Java调用C语言程序时,主要是涉及到操作系统底层的事件。这种时间Java无法处理,例如用户上传一个视频文件,需要后台给视频加上水印,或者后台分离视频流和音频流。只能通过调用C语言处理。
使用Java如何去调用C语言的接口呢?使用Java的JNI技术。
具体调用步骤如下:
1.首先创建Java文件 HelloJni.java ,并创建native方法。
2.编译Java文件并生成java头文件。
3.创建C语言文件,HelloWorld.c。
4.生成动态链接库文件 libhello.so。
5.设置动态链接库文件的目录。
6.把刚才生成的so文件拷贝到/home/lib下,然后执行class文件。
㈣ 怎样在linux环境下使用java调用C++动态链接库时将图片字节流传到C++方法的void*参数中(使用的JNA)
的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。
如下是详细讲解:
1、JAVA中所需要做的工作
在JAVA程序中,首先需要在类中声明所调用的库名称,如下:
static {
System.loadLibrary(“goodluck”);
}
在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。
还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具体实现。如下:
public native static void set(int i);
public native static int get();
然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。
例如程序TestDll.java,内容为:
public class TestDll
{
static
{
System.loadLibrary("goodluck");
}
public native static int get();
public native static void set(int i);
public static void main(String[] args)
{
TestDll test = new TestDll();
test.set(10);
System.out.println(test.get());
}
}
用javac TestDll.java编译它,会生成TestDll.class。
再用javah TestDll,则会在当前目录下生成TestDll.h文件,这个文件需要被C/C++程序调用来生成所需的库文件。
2、C/C++中所需要做的工作
对于已生成的.h头文件,C/C++所需要做的,就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面,就可以用JAVA调用C/C++所实现的功能了。
接上例子。我们先看一下TestDll.h文件的内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class TestDll */
#ifndef _Included_TestDll
#define _Included_TestDll
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_TestDll_get (JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_TestDll_set (JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
在具体实现的时候,我们只关心两个函数原型
JNIEXPORT jint JNICALL Java_TestDll_get (JNIEnv *, jclass);
和
JNIEXPORT void JNICALL Java_TestDll_set (JNIEnv *, jclass, jint);
这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。
下面我们用TestDll.cpp文件具体实现这两个函数:
#include "TestDll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_TestDll_get (JNIEnv *, jclass)
{
return i;
}
JNIEXPORT void JNICALL Java_TestDll_set (JNIEnv *, jclass, jint j)
{
i = j;
}
编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件。并且名称要与JAVA中需要调用的一致,这里就是goodluck.dll
把goodluck.dll拷贝到TestDll.class的目录下,java TestDll运行它,就可以观察到结果了。
3、你想保存一个"\sample\myfile.txt"到变量str中,原本就要写成
㈤ java用jna调用C语言dll接口中的回调函数怎么写
简单的你会写,那就好办,直接上代码
{
{
/**
*登录回调
*/
voidinvoke(StringuserId,longretCode,StringretMsg);
}
/**
*注册一个登录回调方法.此方法是dll提供的
*/
voidRegisterLoginReply(LoginReplyloginReply);
}
/**
*实现登录回调方法
*/
.LoginReply{
@Override
publicvoidinvoke(StringuserId,longretCode,StringretMsg){
log.info("登录回调方法:{},{},{}",userId,retCode,retMsg);
}
}
//设置登录回调
api.RegisterLoginReply(loginReplyCallBack);
㈥ jna如何调用c
通过 jni 中转。
参考我另一个回答:
http://..com/question/175483166073554524.html?oldq=1
㈦ JNA调用C的DLL,如何取回当初传入的字符指针的修改值
C代码extern "C" int _declspec(dllexport) getXMLResult(char *result){result = "abcd";return 20;}这个函数的目的是传入字符指针,在函数内容修改指针指向的字符串内容java代码public class JNATest {
// This is the standard, stable way of mapping, which supports extensive
// customization and mapping of Java to native types.
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary("TestDLL.dll", CLibrary.class);
//函数声明byte[]和String都试过,都不行,改变不了传递进去的字符串
int getXMLResult(byte[] result);}/*** @param args*/public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("begin");
//WString s = new WString("Hello, World");
//System.out.println("s="+s.toString());
byte[] c = {'a','a','a','a'};
System.out.println("c="+Native.toString(c));
//ByteByReference[] iref = new ByteByReference[4];
int i = CLibrary.INSTANCE.getXMLResult(c);
System.out.println("i="+i);
System.out.println("c="+Native.toString(c));
//System.out.println("s="+s.toString());
System.out.println("end");}}Java中byte[] c初始化,调用DLL中函数,但byte[] c的值没有被修改。
===============================================================
㈧ java用jna调用C的时候怎么获取C中输出参数
你先在C环境下调用client_sdk_send_return()函数进行测试,确保不是此函数本身导致的问题。
如果不是,再检查包装函数时是否参数传递有误。
㈨ JNA 调用c++函数的出错,java能加载库,但是找不到c++写的函数
调用C++编译的代码能调用到库但是找不到函数,应该是因为C++编译器会破坏函数的名称。
对此,一般网上能查到两种方法解决:
用extern C ,功能是将部分代码用C编译器进行编译,因为 C编译器不会改变函数的函数名,Java中就可以用代码中的函数名调用了。
用def模板
注1:这里说的方法你需要自己去查一下,别人的文章会写得比较清楚,看完整的文章能学到更多。
注2: 对于C和C++编译器对函数名的影响,这里和你说一下如何查看:你想看看C++编译器编译的DLL的方法名可以用depends反编译程序,把dll拖进depends程序窗口,左边会有依赖树,点击最顶端你的“库名.dll”,右边就能看到dll中函数被C++编译之后的名字。如下图:
用C编译的DLL: