java调用Dll
- 格式:docx
- 大小:18.04 KB
- 文档页数:3
JAVA调用SDK动态链接库一、案例简述JA V A作为跨平台语言,开发中难免遇到跨平台调用接口方法,近期在项目定制开发过程中,现场需要JA V A平台通过DLL动态链接库设置DVR设备功能,如设置获取DVR设备白名单功能、开启关闭白名单功能、获取设置DVR设备码流是否加密、设置获取DVR设备的AES码流加密信息(包括加密密码、加密方式、加密瞬间等信息)等功能。
二、案例分析和解决过程初始化DLL动态库需要通过接口实体初始化DLL动态库,详细定义格式如下:public interface HCNetSDK extends StdCallLibrary {public static final String path ="C:\\Tools\\HCNetSDK_v4.1.5.61_20151015_WIN64\\lib\\HCNetSDK";HCNetSDK INSTANCE = (HCNetSDK)Native.loadLibrary(path, HCNetSDK.class);}其中:path为DLL动态库的路径,定义DLL动态库方法中的对象INSTANCE为DLL 动态库初始化的实例动态库方法的对象定义需要实现Structure,并重写Structure中的getFieldOrder方法,详细声明如下:public static class LPNET_DVR_DEVICEINFO_V40 extends Structure {public NET_DVR_DEVICEINFO_V30 struDeviceV30;public byte bySupportLock;public byte byRetryLoginTime;public byte byPasswordLevel;public byte byRes1;public int dwSurplusLockTime;public byte[] byRes2 = new byte[256];@Overrideprotected List getFieldOrder() {return Arrays.asList(new String[] {"struDeviceV30", "bySupportLock","byRetryLoginTime", "byPasswordLevel","byRes1", "dwSurplusLockTime", "byRes2"});}}其中:变量属性中byte[]对字节长度有严格要求,必须长度一致,否则调用时会出现JDK源代码错误。
Java调用C# DLL的方法简介By 潘伟2012-8-7关于java调用C# 封装的DLL文件的方法第一种:java利用JNA进行调用思路:C#源码生成COM组件(dll和tlb文件),再利用C++进行封装,java通过JNA调用C++封装的DLL。
第二种:java利用jacob进行调用第一种java利用JNA调用C# DLL需安装Visual Studio 2010 ,下载jna.jar(解压放置于jdk_home/jre/lib/ext目录下)。
第一步:利用C#写COM组件1、新建一个类库项目(文件—新建—项目—类库;命名:COMTest);//根据实际需要取文件名2、生成.cs主文件;COMTestClass.cs3、右键点击工程->应用程序->程序集信息->使程序集com可见,打上勾4、右键点击工程->生成->为com Interop注册打上勾5、设置强签名(由于.Net下编译的COM组件并等同于C编译的COM组件,所以存在必须在运行目标机器注册的情况,对此.Net下编译的COM组件必须为程序进行签名,即强命名密钥;)打开Visual Studio Command Prompt 输入:sn -k MyKeyFire.snk 生成MyKeyFire.snk 文件,注意路径。
(.snk文件可以随意取,但.snk后缀名别忘记了)在签名标签中选中为程序集签名,选择刚刚生成的强名称文件MyKeyFire.snk 。
6、在“解决方案资源管理器”中找到节点“Properties”打开AssemblyInfo.cs文件如下图7、将[assembly: ComVisible(false)]属性改成[assembly: ComVisible(true)]如下图8、编译程序,\bin\Debug目录中会生成COMTest.dll 和COMTest.tlb文件。
第二步:利用C++进行再封装1、创建C++ DLL项目,新建项目->VC++->Win32 项目(名称:COMTest_Bridge)->下一步->应用程序类型:DLL2、添加类,类名:COMTest_Bridge,.h名:COMTest_Bridge.h,.cpp名:COMTest_Bridge.cpp,然后生成项目;3、把第一步生成的COMTest.dll 和COMTest.tlb文件放入C++项目下的Debug文件夹下。
java利⽤jni调⽤dll⽅法准备⼯作:(1) jni4net 是⼀个开源的项⽬(2) jni4net-0.8.8.0.zip 中是⼯具的所有⽂件,包含⽰例下载后解压是这样的打开lib下边有你需要⽤到的jar包和dll这是关键。
创建C#程序:打开vs创建⼀个类库com.demo.lib项⽬,写上测试程序。
HelloWorld.csresult.csUser.cs编译成功之后,会在bin下的Debug下⽣成相关的dll。
使⽤proxygen⼯具来⽣成proxy类.jni4net-0.8.8.0-bin\bin下就有proxygen⼯具,可以直接在该⽬录下打开cmd,执⾏命令:.\proxygen.exe "DLL所在路径" -wd "java项⽬根路径"此处我是直接在bin下建了⼀个⽂件夹,⽤于存放⽣成的⽂件。
⽣成之后,需要将所有⽂件拷到java项⽬根路径下。
执⾏后会出现以下⽂件然后将jni4net的相关⽂件都拷到java项⽬的根路径下,执⾏build.cmd⾥⾯的脚本需要修改成你对应的项⽬路径。
错误提⽰:执⾏过程中如果提⽰你某些程序包不存在,说明你没有放到项⽬路径下,或者说,你没有项⽬中没有相关的jar包。
如果提⽰你csc.exe是不可执⾏的命令,说明你没有配置环境变量,将PATH中加上路径:C:\WINDOWS\\Framework\v4.0.30319(环境变量之间⽤英⽂分号;隔开),其他⽅法也可以实现。
执⾏成功之后会⽣成⼀个dll⼀个jar。
这两个是后边需要⽤到的。
java部分我采⽤的开发⼯具是IDEA,我在项⽬根⽬录下,建了⼀个⽂件夹叫,lib,然后将两个jar包拷到lib下⾯。
记住此处要将jar包添加到项⽬中去。
dll的话,我是采⽤的第三⽅路径,别的⽅法也可以,我简单阐述⼀下我的⽅法。
我将剩余的dll拷到e盘下dll⽂件夹中,然后在配置⽂件中,配置上相关的路径。
解决java调⽤dll报Unabletoloadlibrary错误的问题如下:1、确保路径下有该dll⽂件2、dll和jdk必须确保同样是64位或者32位。
3、地址url中不能出现“/”,必须是”\”。
4、路径⼀定要对。
5、如果有同样的⽂件名出现,要在路径后⾯加上“.dll”,⽐如:System.getProperty(“user.dir”)+”\library”+”\PlayCtrl.dll”补充知识:Java语⾔调⽤第三⽅dll⽂件的使⽤⽅法 System.load()或System.loadLibrary()Java调⽤第三⽅dll⽂件的使⽤⽅法public class OtherAdapter {static{//System.loadLibrary("Connector");//载⼊需要调⽤的dll Connector.dllSystem.load("d://Connector.dll");//载⼊dll Connector.dll}//⽤native关键字修饰将被其它语⾔实现的⽅法//dll⽂件中对应的函数声明public native static int _PWLogon(String lpszDS,String lpszUser,String lpszPWD);//函数声明public native static void _PWLogout();public native static String _GetPWLastError();public native static String _GetPWFolders(long lParentFolderno);public native static String _GetPWDocuments(long lFolderno);public native static String _GetPWFiles(long lFolderno,long lDocno);//public native static String pirntStr(String msg);//函数声明public static void main(String[] args){//本地⽅法的调⽤int rs=_PWLogon("服务器","账号","密码");System.out.println("⽤户登录状态:"+rs);if(rs==1){System.out.println("获取顶级⽬录:"+_GetPWFolders(0));System.out.println("获取⽗⼦⽬录:"+_GetPWDocuments(54));System.out.println("下载指定⽂件:"+_GetPWFiles(54,2));_PWLogout();}else{System.out.println("获取错误信息:"+_GetPWLastError());}}}以上这篇解决java调⽤dll报Unable to load library错误的问题就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
java使⽤JNA(JavaNativeAccess)调⽤dll的⽅法JNA(Java Native Access):建⽴在JNI之上的Java开源框架,SUN主导开发,⽤来调⽤C、C++代码,尤其是底层库⽂件(windows中叫dll⽂件,linux下是so【shared object】⽂件)。
JNI是Java调⽤原⽣函数的唯⼀机制,JNA就是建⽴在JNI之上,JNA简化了Java调⽤原⽣函数的过程。
JNA提供了⼀个动态的C语⾔编写的转发器(实际上也是⼀个动态链接库,在Linux-i386中⽂件名是:libjnidispatch.so)可以⾃动实现Java与C之间的数据类型映射。
从性能上会⽐JNI技术调⽤动态链接库要低。
复制代码代码如下:main.h⽂件#ifndef __MAIN_H__#define __MAIN_H__#include <windows.h>/* To use this exported function of dll, include this header* in your project.*/#ifdef BUILD_DLL#define DLL_EXPORT __declspec(dllexport) __stdcall#else#define DLL_EXPORT __declspec(dllimport) __stdcall#endif#ifdef __cplusplusextern "C"{#endifint DLL_EXPORT add(int a,int b);#ifdef __cplusplus}#endif#endif // __MAIN_H__main.cpp#include "main.h"// a sample exported functionint DLL_EXPORT add(int a ,int b){return a+b;}extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {switch (fdwReason){case DLL_PROCESS_ATTACH:// attach to process// return FALSE to fail DLL loadbreak;case DLL_PROCESS_DETACH:// detach from processbreak;case DLL_THREAD_ATTACH:// attach to threadbreak;case DLL_THREAD_DETACH:// detach from threadbreak;}return TRUE; // succesful}复制代码代码如下://import com.sun.jna.Library; cdecl call调⽤约定import com.sun.jna.Native;import com.sun.jna.Platform;import com.sun.jna.win32.StdCallLibrary;public class main {public interface CLibrary extends StdCallLibrary { //cdecl call调⽤约定时为Library CLibrary INSTANCE = (CLibrary)Native.loadLibrary("forjava",CLibrary.class); public int add(int a,int b);}public static void main(String[] args) {System.out.print(CLibrary.INSTANCE.add(2,3));}}。
Java调⽤dll⽂件的实现解析⽬录Java调⽤dll⽂件环境接下来进⼊正⽂Java调⽤dll⽂件⼏种常见⽅式Java调⽤动态库需要关注的问题⼀.数据类型对应关系⼆.Jnative调⽤dll三.JNA调⽤dllJava调⽤dll⽂件近期根据C++做了⼀个图⽚质量检测的项⽬,⽬前需要在在java中进⾏调⽤,所以先在C++上⽣成dll⽂件,然后基于java调⽤dll⽂件实现功能。
环境C++:VS2017(之前配置opencv真是要了⽼命)java:idea2020+jdk1.8。
注意:jdk安装的时候⼩⼼点,path路径容易点编辑,千万别新建,会覆盖的。
接下来进⼊正⽂1. 创建Java项⽬,假设定义HelloWorld函数,其中“winproject1”是等会要调⽤的dll⽂件,现在进⼊cmd并cd到当前⽬录下⾯,然后javah -jni HelloWorld.HelloWorld,这样会在⽬录下⾯⽣成⼀个HelloWorld_HelloWorld.h。
等会需要将这个头⽂件移到之前安装jdk⽬录⾥的include下⾯,如:D:%你的路径%\Java\include。
2. 打开vs2017,创建⼀下新的控制台项⽬,然后需要配置项⽬包含⽬录的路径,将下⾯两个路径加进去,保险点还可以在附加⽬录⾥⾯加上这些路径。
vs2017中编写上⾯头⽂件中的代码:JNIEXPORT void JNICALL Java_HelloWorld_HelloWorld_sayHello (JNIEnv *, jobject, jstring, jstring, jstring, jstring) { cout<<"hello world!"<<endl; }**注:**其中#include "single_check.h"就是我定义检测函数的头⽂件,在下⾯的函数中可以调⽤⾃⼰定义的函数,从⽽让java 执⾏⾥⾯的内容,可以调⽤函数。
Java调用C#的DLL的最佳实践2021.4.1需求背景,甲方以前有个项目用C#开发,现在我们用Java开发的项目业务需要调用C#的加密解码工具。
1.开发工具Visual Studio 2019提前安装好开发工具和组件库我在管网下载了社区版,免费。
安装好安装组件库包括.NET桌面开发、使用C++的桌面开发、通用Windows平台开发。
2.以管理员方式启动vs(项目涉及到注册com组件,必须以管理员启动才能完成),新建c#项目这里一定要注意,选择语言C#、项目类型选择库、这时有三个类库,如上的2个,都不能选。
这是坑。
选下面这个,类库(.NET Framework)输入项目名称:Invoke解决方案名称:DLL_of_CSharp_calling_by_Java注意选择框架:必须选择4,这个都是坑,后面进行不下去的。
3.设置c#项目首先,右键刚刚新建的Invoke项目,点击属性修改程序集,是COM可见。
我的如下继续设置项目属性。
点击生成我选择64位,勾选COM互操作注册。
千万记得保存。
4.新建需要被调用的CSharp类代码项目默认帮我们创建了一个Class1.cs文件。
我们给它重命名为MClass.cs。
并给class MClass添加两个方法。
加密、解密。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Security.Cryptography;namespace Invoke{public class MClass{public string Encrypt(string pToEncrypt, string sKey){using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()){byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);System.IO.MemoryStream ms = new System.IO.MemoryStream();using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)){cs.Write(inputByteArray, 0, inputByteArray.Length);cs.FlushFinalBlock();cs.Close();}string str = Convert.ToBase64String(ms.ToArray());ms.Close();return str;}}public string Decrypt(string pToDecrypt, string sKey){byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()){des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);System.IO.MemoryStream ms = new System.IO.MemoryStream();using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write)){cs.Write(inputByteArray, 0, inputByteArray.Length);cs.FlushFinalBlock();cs.Close();}string str = Encoding.UTF8.GetString(ms.ToArray());ms.Close();return str;}}}}然后右键项目,点击生成生成成功,在下面看到关键文件Invoke.dll。
Java调⽤dll⽅法使⽤JNA框架⽐⽤原来JNI要⽅便多了,对于DLL不需要额外的包装,直接就能够使⽤:1.JNA框架 a.定义:JNA(Java Native Access)框架是⼀个开源的Java框架,是SUN公司主导开发的,建⽴在经典的JNI的基础之上的⼀个框架 b.作⽤:JNA提供⼀组Java⼯具类⽤于在运⾏期动态访问系统本地库(native library:如Window的dll)⽽不需要编写任何Native/JNI代码。
开发⼈员只要在⼀个java接⼝中描述⽬标native library的函数与结构,JNA将⾃动实现Java接⼝到native function的映射。
c.导⼊maven依赖<dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>5.5.0</version></dependency>2.调⽤科⼤讯飞windows api的⽅法public class XunfeiSpeech {public interface MscLibrary extends Library {// DLL⽂件默认路径为项⽬根⽬录,若DLL⽂件存放在项⽬外,请使⽤绝对路径MscLibrary INSTANCE = Native.load("D:\\app\\yuyinhecheng\\bin\\msc_x64", MscLibrary.class);int MSPLogin(String username, String password, String param);int MSPLogout();String QTTSSessionBegin(String params, IntByReference errorCode);int QTTSTextPut(String sessionID, String textString, int textLen, String params);Pointer QTTSAudioGet(String sessionID, IntByReference audioLen, IntByReference synthStatus, IntByReference errorCode);int QTTSSessionEnd(String sessionID, String hints);}... 然后在Java代码中就可以使⽤了:int loginCode = MscLibrary.INSTANCE.MSPLogin(null, null, login_params);。
java调⽤c#dll⽂件配置1 在强⼤的c#语⾔和java语⾔之间,⼆者难免会因为某些特殊的要求会相互调⽤。
下⾯就以java调⽤c#的dll为例做详细介绍1 在vs中的环境设置如下图,图⽚中程序仅作为讲解程序,在项⽬编译成功的前提下,右键项⽬—》应⽤程序—》⽬标框架【选择如下图,根据机器的.netframework环境决定,⼀般⽤4】--》点开程序集信息—》勾选是程序集COM可见复选框,然后再重新⽣成项⽬2 准备已⽣成好的dll⽂件,其中主要类是lcjPlug_v01.dll,Newtonsoft.Json.dll是作为引⽤dll,把⼆者放到相同的⽂件夹下,如下图3 找到指定路径下的cmd.exe 以管理员⾝份运⾏标号1:进⼊到存储dll的盘符下标号2:进⼊存储dll的⽂件下标号3:找到如下路径【C:\Windows\\Framework64\v4.0.30319\】在后跟regasm (需要注册的)dll⽂件如下 dll分为32和64位之分,要根据电脑位数来选择相应的⽂件夹C:\Windows\\Framework\v4.0.30319\regasm lcjPlug_v01.dll(32位)C:\Windows\\Framework64\v4.0.30319\regasm lcjPlug_v01.dll(64位)4 回车,等待结果,结果会显⽰注册成功5 若注册过程中提⽰不是有效程序集1 请检查dll的环境配置是否完好,.net framework是否选择的正确2 注册时选择的Framewrok是否和当前注册的dll位数相匹配3 Framework注册时是否和dll环境配置的.net framework保持⼀致,有版本有向下兼容性4 如果要正常注册dll,regasm必须能够⽀持dll对应的Framework的版本。
5 确认jacob的版本和放置的位置。
Java调⽤.dll⽂件的⽅法到这⾥下载JNative开源项⽬,我下载的是1.3.2解压JNative-<st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899">1.3.2</st1:chsdate>.zip获得三个⽂件,分别是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar 。
JNativeCpp.dll Windows下⽤的,拷贝到windows / system32⽬录下;libJNativeCpp.so Linux下的,拷贝到系统⽬录下;JNative.jar 这是⼀个扩展包,导⼊⼯程LIB中或将其拷贝到jdk\jre\lib\ext 下,系统会⾃动加载。
我的项⽬将使⽤JNative组件调⽤⼀个测试应⽤服务器状态的TestAppSvr.dll⽂件,Dll⽂件中包含⼀个TestConnect()⽅法,返回⼀个整形的结果(1或0)⾸先配置好JNative组件的windows环境:将Native要⽤到JNativeCpp.dll放在系统盘的\WINDOWS\system32下将JNative.jar导⼊⼯程中,新建⼀个调⽤类:java 代码复制代码代码如下:package jody;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import org.xvolks.jnative.JNative;import org.xvolks.jnative.Type;import org.xvolks.jnative.exceptions.NativeException;public class AppSvrTestConnect {public AppSvrTestConnect() {}/*** 测试应⽤服务器连接状态** TestConnect* @param ip 应⽤服务器IP* @param port 端⼝* @param intrcpt 是否采⽤数据压缩⽅式 1 :true 0:false* @return int 1 :成功 0:失败* @throws NativeException* @throws IllegalAccessException*/private static final int TestConnect(String ip, int port, int intrcpt)throws NativeException, IllegalAccessException {JNative n = null;try {n = new JNative("TestAppSvr.dll", "TestConnect");n.setRetVal(Type.INT);int i = 0;n.setParameter(i++, Type.STRING, ip);n.setParameter(i++, Type.INT, "" + port);n.setParameter(i++, Type.INT, "" + intrcpt);n.invoke();return Integer.parseInt(n.getRetVal());} finally {if (n != null)n.dispose();}}/*** 指定Dll⽂件路径,动态加载本地链接库,测试应⽤服务器连接状态* setDllPath* @param path Dll⽂件的路径,不包含DLL名称例如:windows - d:\test\test\ unix - root/test/test/* @param ip 应⽤服务器IP* @param port 端⼝* @param intrcpt 是否采⽤数据压缩⽅式 1 :true 0:false* @return int 1 :成功 0:失败* @throws NativeException* @throws IllegalAccessException*/public static final int TestConnectFromDllPath(String path,String ip, int port, int intrcpt) throws NativeException, IllegalAccessException{path += "TestAppSvr.dll";System.load(path);return TestConnect(ip,port,intrcpt);}/*** Dll⽂件放在JRE\bin⽬录下⾯,ClassLoader就能通过System.loadLibrary()动态加载本地链接库* TestConnectFromDllPath* @param ip 应⽤服务器IP* @param port 端⼝* @param intrcpt 是否采⽤数据压缩⽅式 1 :true 0:false* @return int 1 :成功 0:失败* @throws NativeException* @throws IllegalAccessException*/public static final int TestConnectFromDllPath(String ip, int port, int intrcpt) throws NativeException, IllegalAccessException{System.loadLibrary("TestAppSvr");return TestConnect(ip,port,intrcpt);}}这个类实现了⼀个静态私有⽅法,⽤来调⽤Dll⽂件中的⽅法返回结果private static final int TestConnect(String ip, int port, int intrcpt)两个静态公共⽅法,分两种⽅式装载DLL⽂件public static final int TestConnectFromDllPath(String path,String ip, int port, int intrcpt) //通过DLL⽂件的路径public static final int TestConnectFromDllPath(String ip, int port, int intrcpt) //通过ClassLoader 然后新建⼀个类,调⽤AppSvrTestConnect.java,实现⽅法⼀调⽤,我是将TestAppSvr.dll⽂件与Demo.java放在⼀个⽬录下 ,所以得到Demo.java的路径后就可以得到TestAppSvr.dll的路径,调⽤AppSvrTestConnect.TestConnectFromDllPath()⽅法后就能返回正确的信息.⽅法⼆是已经将TestAppSvr.dll放在了Jre\bin⽬录下,在JVM的Classloader的时候会⾃动加载,然后通过System.loadLibrary("TestAppSvr")就可以装配DLL⽂件.java 代码复制代码代码如下:public class Demo {public int getInfo() throws NativeException, IllegalAccessException{String path=getClass().getResource(File.separator).getPath();path = path.substring(1,path.length());System.out.println(path); //得到DLL⽂件的路径String ip = "192.168.0.48"; //服务器IPint port = 221; //端⼝int intrcpt = 1; //数据压缩⽅式传送,1为采⽤;0为不采⽤//⽅法1 传⼊Dll⽂件的路径//int info = AppSvrTestConnect.TestConnectFromDllPath(path, ip, port, intrcpt);//⽅法2 Dll⽂件已经放在JRE\bin⽬录下⾯int info = AppSvrTestConnect.TestConnectFromDllPath(ip, port, intrcpt);//1为成功,0为失败if (info == 1)System.out.println("应⽤服务器可⽤。
JAVA如何调用C或者C++生成的dll本文为在 32 位 Windows 平台上实现 Java 本地方法调用dll的示例。
由于对C语言不是很熟悉,有部分内容摘自网络。
第一步、编写java文件package com.ztsoft.jni;public class MyDll {static {System.loadLibrary("MyDll");}public native static String HelloWord();public native static String HelloWord(int num);}第二步、编译生成h文件1、编译D:\MyE clipse 6.5M1 Blue\w orkspace\javaWorkS pace\src>javac com/ztsoft/jni/MyDll.java(生成MyDll.class位于jni目录下)2、生成h文件D:\MyE clipse 6.5M1 Blue\w orkspace\javaWorkS pace\src>javah com.ztsoft.jni.MyDll(生成com_ztsoft_jni_MyDll.h这个文件位于src目录下)/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_ztsoft_jni_MyDll */#ifndef _Included_com_ztsoft_jni_MyDll#define _Included_com_ztsoft_jni_MyDll#ifdef __cplusplusextern "C" {#endif/** Class: com_ztsoft_jni_MyDll* Method: HelloWord* Signature: ()Ljava/lang/S tring;*/JNIE XPORT jstring JNICALL Java_com_ztsoft_jni_MyDll_HelloWord__(JNIE nv *, jclass);/** Class: com_ztsoft_jni_MyDll* Method: HelloWord* Signature: (I)Ljava/lang/S tring;*/JNIE XPORT jstring JNICALL Java_com_ztsoft_jni_MyDll_HelloWord__I(JNIE nv *, jclass, jint);#ifdef __cplusplus}#endif#endif第三步、编写C++文件在具体实现的时候,我们只关心两个函数原型。
JAVA调用第三方DLL的方法举例:Windows平台的部署。
首先将将动态连接库(AA.dll)拷贝到PATH环境变量指定的目录下, 即动态连接库的搜索路径是由PATH环境变量指定。
然后把AAbean.jar加入环境变量classpath中。
需要注意的是加载的dll和jar文件是你所需要的正确版本, 避免交叉引用。
Linux/Unix平台AA Javabeans的部署也类似,所不同的是:Linux/Solaris平台动态连接库的搜索路径是由LD_LIBRARY_PATH环境变量指定;Aix平台动态连接库的搜索路径是由LIBPATH环境变量指定;HP-UX平台动态连接库的搜索路径是由SHLIB_PATH环境变量指定。
开发环境下临时部署:在JAVA类中调用System.getProperty(“java.library.path”),根据输出的路径将AA.dll拷贝到该目录下。
然后把AAbean.jar加入环境变量classpath中附件:System.getProperty()参数大全java.version Java Runtime Environment versionjava.vendor Java Runtime Environment vendorjava.vendor.url Java vendor URLjava.home Java installation directoryjava.vm.specification.version Java Virtual Machine specification versionjava.vm.specification.vendor Java Virtual Machine specification vendor Java Virtual Machine specification namejava.vm.version Java Virtual Machine implementation versionjava.vm.vendor Java Virtual Machine implementation vendor Java Virtual Machine implementation namejava.specification.version Java Runtime Environment specification versionjava.specification.vendor Java Runtime Environment specification vendor Java Runtime Environment specification namejava.class.version Java class format version numberjava.class.path Java class pathjava.library.path List of paths to search when loading librariesjava.io.tmpdir Default temp file pathpiler Name of JIT compiler to usejava.ext.dirs Path of extension directory or directories Operating system nameos.arch Operating system architectureos.version Operating system versionfile.separator File separator ("/" on UNIX)path.separator Path separator (":" on UNIX)line.separator Line separator ("\n" on UNIX) User''s account nameuser.home User''s home directoryuser.dir -。
这是一段J A V A调用T S C条码打印机的代码�有详细的注释�1�需要把d l l文件拷贝到c:\w i n d o w s\s y s t e m32目录下2,工程里面需要加载J N a t i v e.j a r包�网上很多下载的�<;p r e c l a s s=";h t m l"; n a m e=";c o d e";>;/**************************************************************** ****************$H e a d e r$*$R e v i s i o n$*$D a t e$**============================================================================== **C o p y r i g h t(c)2001-2006P r i m e t o n T e c h n o l o g i e s,L t d.*A l l r i g h t s r e s e r v e d.**C r e a t e d o n2011-11-30D i c k y P e n g h u a i b i n g*******************************************************************************/ p a c k a g e c o m.s i e.b a r c o d e;i m p o r t o r g.x v o l k s.j n a t i v e.J N a t i v e;i m p o r t o r g.x v o l k s.j n a t i v e.e x c e p t i o n s.N a t i v e E x c e p t i o n;p u b l i c c l a s s B a r c o d e T e s t{/***@p a r a m a r g s*/p u b l i c s t a t i c v o i d m a i n(S t r i n g[]a r g s)t h r o w s N a t i v e E x c e p t i o n, I l l e g a l A c c e s s E x c e p t i o n{B a r c o d e T e s t.b a r c o d e_p r i n t(";B A R03743902";);}//打印方法�传入需要打印的条码参数p u b l i c s t a t i c v o i d b a r c o d e_p r i n t(S t r i n g b a r c o d e_s t r)t h r o w s N a t i v e E x c e p t i o n, I l l e g a l A c c e s s E x c e p t i o n{//T O D O A u t o-g e n e r a t e d m e t h o d s t u b//系统加载d l l文件有两种写法1.l o a d L i b r a r y方法:把d l l文件拷贝到c:\w i n d o w s\s y s t e m32目录下,引用时只需写d l l名字2.l o a d方法:写d l l文件的完整路径S y s t e m.l o a d L i b r a r y(";T S C L I B";);//T S C L I B是T E S打印机的d l l文件//参数说明I n t e r f a c e F u n d l l名,A d d Z h i Y e函数名J N a t i v e o p e n p o r t=n e w J N a t i v e(";T S C L I B";,";o p e n p o r t";);//o p e n p o r t.s e t R e t V a l(T y p e.S T R I N G);o p e n p o r t.s e t P a r a m e t e r(0,";T S C T T P-342P r o";);//函数执行o p e n p o r t.i n v o k e();i n t i=0;/*s e t u p(a,b,c,d,e,f,g)说明:设定卷标的宽度、高度、打印速度、打印浓度、感应器类别、g a p/b l a c k m a r k垂直间距、g a p/b l a c k m a r k偏移距离)参数:a:字符串型别�设定卷标宽度�单位m mb:字符串型别�设定卷标高度�单位m mc:字符串型别�设定打印速度�(打印速度随机型不同而有不同的选项)1.0:每秒1.0吋打印速度1.5:每秒1.5吋打印速度2.0:每秒2.0吋打印速度3.0:每秒3.0吋打印速度4.0:每秒4.0吋打印速度5.0:每秒5.0吋打印速度6.0:每秒6.0吋打印速度d:字符串型别�设定打印浓度�0~15�数字愈大打印结果愈黑e:字符串型别�设定使用感应器类别0表示使用垂直间距传感器(g a p s e n s o r)1表示使用黑标传感器(b l a c k m a r k s e n s o r)f:字符串型别�设定g a p/b l a c k m a r k垂直间距高度�单位:m mg:字符串型别�设定g a p/b l a c k m a r k偏移距离�单位:m m�此参数若使用一般卷标时均设为0**/J N a t i v e s e t u p=n e w J N a t i v e(";T S C L I B";,";s e t u p";);s e t u p.s e t P a r a m e t e r(i++,";50";);s e t u p.s e t P a r a m e t e r(i++,";25";);s e t u p.s e t P a r a m e t e r(i++,";3";);s e t u p.s e t P a r a m e t e r(i++,";5";);s e t u p.s e t P a r a m e t e r(i++,";5";);s e t u p.s e t P a r a m e t e r(i++,";0";);s e t u p.s e t P a r a m e t e r(i++,";5";);s e t u p.s e t P a r a m e t e r(i++,";0";);s e t u p.i n v o k e();/*使用条形码机内建条形码打印*5.b a r c o d e(a,b,c,d,e,f,g,h,I)说明:使用条形码机内建条形码打印参数:a:字符串型别�条形码X方向起始点�以点(p o i n t)表示。
JA V A调用vb编写的dll相关问题1.用vb建立一个dll动态链接库:2.输入如下代码:具体代码如下:Function SayHello() As StringSayHello = "这是一个测试!"End Function点击工程1(工程1)--->工程1 属性(E)...--->通用--->工程名称(N)将工程名称改为“test”,这个可以自己定义想要的名称,方便在java中调用注意:这里如果不修改,调用时会报错:Exception in thread "main" FailException: Can't get object clsid from progid4.文件--->生成test.dll注意:这里选择路径为C:\WINDOWS\SYSTEM32下,方便在注册表中查看5.打开注册表6.在HKEY_CLASSES_ROOT目录下找到刚才的dll注册文件注意这个工程1.class1就是第3步中没有更改工程名的后果正确的注册表信息是下图:7.打开Eclipse输入如下代码:import com.jacob.activeX.ActiveXComponent;import .*;public class HKTest{public static void main(String[] args){ActiveXComponent pp = new ActiveXComponent("test.class1");try {S ystem.out.println(Dispatch.call(pp, "SayHello"));} catch (Exception e) {e.printStackTrace();}}}下面讲一下在Eclipse中加载外部jacob.jar包的方法1.下载jacob包链接: /s/1tloi 密码: rfla这是我自己在用的jacob包2.JRE System Library[jre6]右键--->Build Paht---->Configure Build Paht...--->Add External JARs...选择jacob.jar点击打开即可3.将下载的jacob包中的jacob-1.18-M2-x86.dll拷贝到D:\Java\jre6\bin目录下,就是你安装java 的目录,我这里是将java安装在D盘。
java中通过JNA调⽤dll---恢复内容开始---1. JNA简单介绍先说JNI(Java Native Interface)吧,有过不同语⾔间通信经历的⼀般都知道,它允许Java代码和其他语⾔(尤其C/C++)写的代码进⾏交互,只要遵守调⽤约定即可。
⾸先看下JNI调⽤C/C++的过程,注意写程序时⾃下⽽上,调⽤时⾃上⽽下。
可见步骤⾮常的多,很⿇烦,使⽤JNI调⽤.dll/.so共享库都能体会到这个痛苦的过程。
如果已有⼀个编译好的.dll/.so⽂件,如果使⽤JNI技术调⽤,我们⾸先需要使⽤C语⾔另外写⼀个.dll/.so共享库,使⽤SUN规定的数据结构替代C语⾔的数据结构,调⽤已有的 dll/so中公布的函数。
然后再在Java中载⼊这个库dll/so,最后编写Java native函数作为链接库中函数的代理。
经过这些繁琐的步骤才能在Java中调⽤本地代码。
因此,很少有Java程序员愿意编写调⽤dll/.so库中原⽣函数的java程序。
这也使Java语⾔在客户端上乏善可陈,可以说JNI是 Java的⼀⼤弱点!那么JNA是什么呢?JNA(Java Native Access)是⼀个开源的Java框架,是Sun公司推出的⼀种调⽤本地⽅法的技术,是建⽴在经典的JNI基础之上的⼀个框架。
之所以说它是JNI的替代者,是因为JNA⼤⼤简化了调⽤本地⽅法的过程,使⽤很⽅便,基本上不需要脱离Java环境就可以完成。
如果要和上图做个⽐较,那么JNA调⽤C/C++的过程⼤致如下:可以看到步骤减少了很多,最重要的是我们不需要重写我们的动态链接库⽂件,⽽是有直接调⽤的API,⼤⼤简化了我们的⼯作量。
JNA只需要我们写Java代码⽽不⽤写JNI或本地代码。
功能相对于Windows的Platform/Invoke和Python的ctypes。
2. JNA技术原理JNA使⽤⼀个⼩型的JNI库插桩程序来动态调⽤本地代码。
开发者使⽤Java接⼝描述⽬标本地库的功能和结构,这使得它很容易利⽤本机平台的功能,⽽不会产⽣多平台配置和⽣成JNI代码的⾼开销。
由于工作原因需要在JA V A开发的项目中调用DELPHI开发的dll动态库,查询了很多资料总结出方法有以下几种:1、通过JNI调用,这种方式如果调用C/C++开发的dll动态库文件没有什么问题.但是问题是库是用DELPHI生成的,用JNI不能直接访问,所以只能用C封装DELPHI的库供JNI访问,但是这样很麻烦,而且双层封装不稳定;又或者在使用DELPHI开发dll时引用一个jni.pas的接口单元,按照JNI的方式编写生成dll这样才可以调用。
下面我举例说明一下怎样在使用DELPHI开发可供JA V A的JNI直接调用的dll:首先用DELPHI新建一个dll工程testDll.dpr;之后我们需要下载jni.pas 加入到我们的工程中,这是国外的高手写的程序单元,它方便我们的Delphi 程序与JA V A 交互。
解压之后里面有两个文件,将其存放在工程的目录下;接下来我们编写Delphi 代码: library testDll; //这里设置动态链接库的名称,因为我们刚才写JA V A 类时是用testDll,所以这里了要设置为testDll:代码完成,我们Ctrl+F9 编译DLL ,生成testDll.dll 后,我们把他复制到Java 工程目录;在JA V A工程中新建一个包名myPackage类名HelloWorld的类:编译执行后,可以看到屏幕打印出:Hello,This is a Test!的字样,说明调用成功!2、通过JNA第三方的JA V A开发组件实现,这种方法调用过程简单实用,而且DELPHI开发dll时不用增加特殊的jni接口,推荐使用:同样,首先用DELPHI新建一个dll工程testDll.dpr,这里就不需要jni.pas了;在JA V A工程里新建一个类Hello.java,然后引入一个jna.jar的包这个可以在网上下载:编译执行后,可以看到屏幕打印出:Hello,This is a Test!的字样,是不是很方便?详细的JNA的API帮助文档可以在网上下载到。
java中调⽤dll⽂件的两种⽅法⼀中是⽤JNA⽅法,另外是⽤JNative⽅法,两种都是转载来的,JNA⽅法:介绍给⼤家介绍⼀个最新的访问本机代码的Java框架—JNA。
JNA(Java Native Access)框架是⼀个开源的Java框架,是SUN公司主导开发的,建⽴在经典的JNI的基础之上的⼀个框架。
⾮常强⼤、易⽤,功能上类似与.NET的P/Invoke。
不堪回⾸的JNI我们知道,使⽤JNI调⽤.dll/.so共享类库是⾮常⾮常⿇烦和痛苦的。
如果有⼀个现有的.dll/.so⽂件,如果使⽤JNI技术调⽤,我们⾸先需要另外使⽤C语⾔写⼀个.dll/.so共享库,使⽤SUN规定的数据结构替代C 语⾔的数据结构,调⽤已有的 dll/so中公布的函数。
然后再在Java中载⼊这个适配器dll/so,再编写Java native函数作为dll中函数的代理。
经过2个繁琐的步骤才能在Java中调⽤本地代码。
因此,很少有Java程序员愿意编写调⽤dll/.so库中的原⽣函数的java程序。
这也使Java语⾔在客户端上乏善可陈。
可以说JNI是Java的⼀⼤弱点!.NET平台上强⼤的P/Invoke⽽在.NET平台上,强⼤的P/Invoke技术使我们Java程序员⾮常羡慕。
使⽤P/Invoke技术,只需要使⽤编写⼀个.NET函数,再加上⼀个声明的标注,就可以直接调⽤dll中的函数。
不需要你再使⽤C语⾔编写dll来适配。
不逊于P/Invoke的JNA现在,不需要再羡慕.NET的P/Invoke机制了。
JNA把对dll/.so共享库的调⽤减少到了和P/Invoke相同的程度。
使⽤JNA,不需要再编写适配⽤的.dll/.so,只需要在Java中编写⼀个接⼝和⼀些代码,作为.dll/.so的代理,就可以在Java程序中调⽤dll/so。
JNA快速启动现在让我们直接进⼊JNA的世界。
你只需要下载⼀个jar包,就可以使⽤JNA的强⼤功能⽅便地调⽤动态链接库中的C函数。
如何在Java中调用DLL方法
2009-06-17 13:19 caitong CSDN 我要评论(0)字号:T | T
Java调用DLL的技术方便易用,使用Java开发前台界面可以更快速,也能带来跨平台性。
使用JNI、Jawin和Jacb使得Java在Windows平台下使用COM和 DLL的更加方便。
AD:2013大数据全球技术峰会低价抢票中
Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台界面可以更快速,也能带来跨平台性。
Java调用C/C写好的DLL库时,由于基本数据类型不同、使用字节序列可能有差异,所以在参数传递过程中容易出现问题。
使用Java调用DLL动态链接库的方案通常有三种:JNI, Jawin, Jacob. 其中JNI(Java Native Interface)是Java语言本身提供的调用本地已编译的函数库的方法,本身具有跨平台性,可以在不同的机器上调用不同的本地库。
Jawin和 Jacob都是的开源项目,都是基于JNI技术的依赖Windows的实现,使得在Windows平台下使用COM和 DLL的更加方便。
JNI
JNI的应用方案是基于Java类和本地函数相映射的。
其使用Java调用DLL的步骤还是相对比较麻烦,不但涉及到Java编程,还涉及到C/C编程。
JNI的使用步骤是:
1.编写Java类,用该类将DLL对外提供的函数服务进行声明,其中的Java方法均声明为native,其方法签名可以自定义,不用实现函数体。
2.用Javah工具将该Java类生成对应的.h头文件。
3.最重要的比较麻烦的一步:编写C/C代码实现.h头文件中声明的函数,该C/C代码中包含jni.h头文件,并且编写代码时使用其中定义好的数据类型作为函数的输入和返回数据类型进行编程。
用这种方法实现数据类型转换。
例如数据类型:boolean(java) à jboolean(jni.h: typedef unsigned char jboolean),在自己编写的C/C代码中使用数据类型jboolean映射Java中的boolean类型。
在该步骤中,可以在C/C代码中调用已经存在的DLL库。
4.另外编写的Java代码时就可以使用该Java类了。
在第3步中,编写C/C函数时,可以使用一个叫interface pointer的env指针来调用JNI提供的一系列(很多)函数,用这些函数来访问JVM的对象和数据。
使用JNI的缺点:使用比较麻烦,需要对已有的DLL进行封装,需要对C/C比较了解。
使用JNI的优点:可以跨平台调用本地库。
Jawin
Jawin的应用方案是基于函数调用时采用原始字节流传递数据的。
就是在Java中指明一个DLL中的某个函数后,通过原始字节流(需要考虑参数数据类型所占的存储字节数及系统使用的字节序列)传递给该DLL函数需要的参数,其返回值也是通过原始字节流解析的方式获得正确的值。
Jawin的使用步骤:
1.环境配置:下载Jawin;Jawin.dll放入工程目录下;Jawin.jar相关jar文件加入到运行库中(LibPath 或者Eclipse下配置工程的BuildPath-AddLibrary)。
2.获得函数指针:new FuncPtr("DllFileName.DLL", "dllFunctionName");
3.用LittleEndianOutputStream将函数需要的参数写入到一个原始字节流NakedByteStream。
4.最重要的一步:调用FuncPtr.invoke()。
传入参数比较复杂。
5.解析上一步的返回值(字节数组)。
第4步中传入的参数包括:
1.指令字符串。
一个"XXX:Y:ZZZ"格式的字符串。
其含义分别是传入参数中的每个字节的数据类型意义、返回值的类型、需要从传入指针中读取的数据(inout类型参数)。
比如:
函数签名int func(int, int, struct s*, char*); //其中struct s*调用完函数后需要读出,struct s 所占字节数为16。
其指令字符串为:IIP16G:I4L4n16L4。
该字符串在解析返回值(字节数组)时,首先应该是返回类型I对应的4个字节,然后是inout类型的参数中n16对应的16个字节。
其中字符串的意义可以在Jawin提供的文件instructions.h中找到,或者在官方文档(Jawin数据指令)中找到常用的一些指令字符串的意义。
2.传入参数的总字节大小。
3.前面写好的传入参数的原始字节流。
4.一个object数组。
5.ReturnFlags,用以根据C/C返回值将C/C的错误转换为Java的异常并抛出。
其中CHECK_NONE表示不检查;CHECK_FALSE和CHECK_WIN32分别表示返回0是FALSE和 SUCCESS,根据是否出错决定是否抛出异常;CHECK_HRESULT表示使用COM模型中的HRESULT作为返回值,其错误码可以配置。
使用Jawin的缺点:不方便调试,几乎所有的错误都抛出同样的异常COMException;需要对数据类型的转换比较了解;不能跨平台,对Windows的依赖性比较强。
使用Jawin的优点:方便使用,不用进行C/C开发,不用对原始DLL进行封装就可以方便使用。
Jacob
Jacob是Java-Com Bridge的缩写,也可以用来调用DLL。
其底层也是使用JNI实现,也具有Windows 的平台依赖性,但是网上有人反映其易用性不如jawin。