网上调用第三方dll组件的方法有很多,作者是通过jna进行调用的,试过com组件封装但是组件,但是一直没有成功,感兴趣的可以试试。
那么首先说一下思路:
思路1
因为是.net的dll文件(net.dll),故无法直接使用jna进行调用,所以作者的思路是将net.dll用c++先引入后,再做成一个c++的dll,供java使用jna直接调用。
-
用C++封装外部dll,这里假设已经有.net的dll文件了,我们直接开始使用C++对net.dll进行封装
下面我们将调用代码写一下,其中我的EncryptLib.dll中存在两个类文件,并提供一个方法,用于外部调用的方法名为EncryptPwd是一个传入两个文本值,返回一个秘钥文本的工具
#ifdef MYLIBAPI
#else
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
MYLIBAPI char* MethodGet(char *name,char *key); //添加函数声明,此函数为生成的C++的dll的外部公开函数
using namespace System;
using namespace EncryptLib;//添加引入的C#的dll名称
char* MethodGet(char *name,char *key)
{
String ^ a = gcnew String(name);//需要将char *转换为托管的String类型,否则失败
String ^ b = gcnew String(key);//需要将char *转换为托管的String类型,否则失败
EncryptFunc ^method = gcnew EncryptFunc();//实例化C#的类即EncryptLib中的类文件
String ^resultString=method->EncryptPwd(a, b);//调用C#的dll中的方法
char* result =(char*)(void*)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(resultString);
return result;
}
代码编写成功后,右键项目,选择生成,即可生成dll文件
- 使用java调用c++的dll
将dll文件放入指定目录中,如“D:\server\Win32Project1.dll”,并将net.dll(即原始dll)放入到jdk的bin目录下,如:C:\ProgramFiles\Java\jdk1.7.0_80\bin的目录下,打开eclipse,新建项目,创建java文件,代码如下
package myGetPass;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class Encrypt {
//使用main方法进行调用即可
public static void main(String[] args) throws Exception{
String methodGet = getPass.instanceDll.MethodGet("154646","46549879788");
System.out.println(methodGet);
}
interface getPass extends Library{
getPass instanceDll=(getPass) Native.loadLibrary("D:\\server\\Win32Project1.dll",getPass.class);
//getPass即当前接口名称,loadLibrary方法,第一个参数为C++的dll路径,并将其中的方法给到getPass这个接口
//这个地方填写C++中定义的方法名称及返回值
String MethodGet(String name, String key);
}
}
- 注意事项:
1.jdk和c++生成的dll保持一致,即都是64位,或都是32位
2.需要将原生的net.dll放置到jdk的bin目录下
3.java方面需要引入jna的jar包,笔者使用的是jna-3.5.1.jar
思路2
用C++将dll引用,然后封装成一个.exe文件,使用java的Runtime.getRuntime().exec()这种方式对exe文件进行调用,并拿到返回值
C++部分代码如下
#include <stdio.h>
#include <stdlib.h>
using namespace System;
using namespace PMTEncryptLib;//添加引入的C#的dll名称
void main(int argc,char *argv[])
{
String ^ a = gcnew String(argv[1]);//需要将char *转换为托管的String类型,否则失bai
String ^ b = gcnew String(argv[2]);//需要将char *转换为托管的String类型,否则失败
EncryptFunc ^method = gcnew EncryptFunc();//实例化C#的类
String ^resultString=method->EncryptPwd(a, b);//调用C#的dll中的方法
char* result =(char*)(void*)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(resultString);
printf(result);
}
java部分的代码如下
public static String getKey(String exePath,String name,String pass)throws Exception{
//此处依次输入可执行文件的路径,及参数即可,
//由于本人的exe文件需要给定两个值,故cmdarr中除路径外,其他还有两个参数
String[] cmdArr = new String[]{exePath, name,pass};
Process process = Runtime.getRuntime().exec(cmdArr);
// int ret = process.waitFor();
InputStreamReader inputStr = new InputStreamReader(process.getInputStream());
BufferedReader br = new BufferedReader(inputStr);
String result=null;
String temp = "";
while((temp = br.readLine())!= null){
result=temp;
}
process.destroy();
br.close();
inputStr.close();
return result;
}
希望能帮到大家!!!