大漠dll说明
1、dm.dll为com类型组件。
2、DmReg.dll 免注册为常规dll。
学习研究时的历程
1、因为大漠是com组件,所以可以使用jacob 调用大漠。但是不支持免注册dll的使用。放弃。
2、网上看的jna不支持com类型dll(其实现在是可以调用的,下文说明),但是能调用免注册dll。因此可以先是用jna调用免注册dll,然后再使用jacob创建dm对象。至此也算是实现了免注册调用dm的功能。
3、但是作为一个伪完美主义者,实在是不能忍受jacob自己还带了俩dll,并且一个项目还引用了两个相同类型的框架(jacob和jna),然后经过我的不懈努力、
不断尝试终于搞定了完全使用jna框架免注册调用dm的方法。实在是网上一点资料搜不到,并且官网文档对新手实在不友好。
jna说明
jna官网:GitHub - java-native-access/jna: Java Native Access
jna本身是不能调用com组件的,但是官方有提供的扩展包可以实现调用。
打开扩展包说明文档,惊喜的发现COM三个字母,然后机翻下大致意思是我们有两种方式可以实现调用com组件,具体使用自己看下例子吧(打开例子我当时是一脸懵)。
使用
jna有两种方式调用,
第一种是继承COMLateBindingObject,官方不推荐,而且使用也不方便。
第二种是注解方式,官方推荐,使用也简单,本文使用该方式。
maven引用
<!--一个工具包,演示代码里有使用-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
<!-- 扩展包已经依赖了这个,可以不用再手动引用了 -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.13.0</version>
</dependency>
<!--jna扩展包-->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.13.0</version>
</dependency>
先封装个调用免注册DmReg.dll设置大漠插件dm.dll路径的类
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
* @author sun
**/
public class DmRegHandler {
/**
* jna 调用标准免注册dll
*/
private interface DmReg extends Library {
DmReg INSTANCE = Native.load("DmReg.dll", DmReg.class);
/**
* SetDllPathA 字符串(Ascii码表示插件所在的路径),整数(0表示STA,1表示MTA)
*/
int SetDllPathA(String format, int args);
/**
* SetDllPathW 字符串(Unicode码表示插件所在的路径),整数(0表示STA,1表示MTA)
*/
void SetDllPathW(String format, int args);
}
/**
* 封装一个静态方法,方便调用
*/
public static int exec() {
return new DmRegHandler().handler();
}
public int handler() {
//获取dm.dll的绝对路径。
String absolutePath = FileUtil.getAbsolutePath("dm.dll");
Console.log("大漠插件路径:{}", absolutePath);
int result = DmReg.INSTANCE.SetDllPathA(absolutePath, 0);
Console.log("免注册调用结果:{}", result == 1 ? "成功" : "失败");
return result;
}
}
再建一个大漠对象对应的接口
@ComObject(progId = "dm.dmsoft") 注解 表示是一个com组件接口。progId 是大漠的对象名。
@ComMethod 注解 表示是dll方法。之后直接调用就可以使用。
指针参数:Variant.VARIANT 也就是大漠文档中说的变参指针。
这里就只粘贴几个方法,用来演示,如果需要别的方法,直接从大漠文档中复制过来 改下就行了。记得加上@ComMethod 注解。
import com.sun.jna.platform.win32.COM.util.annotation.ComMethod;
import com.sun.jna.platform.win32.COM.util.annotation.ComObject;
import com.sun.jna.platform.win32.Variant;
/**
* @author sun
**/
@ComObject(progId = "dm.dmsoft")
public interface ComBean {
@ComMethod
String Ver();
@ComMethod
long FindPic(int x1, int y1, int x2, int y2, String pic_name, String delta_color, double sim, int dir, Variant.VARIANT intX, Variant.VARIANT intY);
@ComMethod
long Reg(String reg_code, String ver_info);
@ComMethod
long SetPath(String path);
@ComMethod
String GetPath();
@ComMethod
long MoveTo(int x, int y);
@ComMethod
long LeftDoubleClick();
}
正式使用
public static void main(String[] args) {
//调用免注册
int exec = DmRegHandler.exec();
if (exec != 1){
Console.log("免注册调用失败!");
return;
}
Ole32.INSTANCE.CoInitializeEx(Pointer.NULL, Ole32.COINIT_MULTITHREADED + Ole32.COINIT_SPEED_OVER_MEMORY);
ObjectFactory objectFactory = new ObjectFactory();
ComBean object1 = objectFactory.createObject(ComBean.class);
Console.log(object1.Ver());
Console.log("SetPath:{}", object1.SetPath("D:\\Users\\sun\\Desktop\\"));
Console.log("Path:{}", object1.GetPath());
//指针参数初始化。
VARIANT x = new VARIANT(new IntByReference());
VARIANT y = new VARIANT(new IntByReference());
Console.log("FindPic:{}", object1.FindPic(0, 0, 2000, 2000, "5.bmp", "000000", 0.9, 0, x, y));
Console.log("{}:{}", x.getValue(), y.getValue());
object1.MoveTo(x.intValue(), y.intValue());
object1.LeftDoubleClick();
objectFactory.disposeAll();
}
注意事项
1、jdk使用32位的。
2、使用管理员方式运行。
3、DmReg.dll和dm.dll放到classpath下。
4、未付费用户只能使用一些基础方法。使用高级方法需要调用 long Reg(reg_code,ver_info)进行收费注册。
5、2023-07-03更新:
改了下代码DmRegHandler.exec() 添加了返回值,用来判断免注册是否调用成功。