java jna免注册调用大漠插件及指针参数方法调用

大漠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、讨论:66352127

2023-07-03更新:

改了下代码DmRegHandler.exec() 添加了返回值,用来判断免注册是否调用成功。

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值