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官网:https://github.com/java-native-access/jna

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)
         */
        void SetDllPathA(String format, int args);
        /**
         * SetDllPathW  字符串(Unicode码表示插件所在的路径),整数(0表示STA,1表示MTA)
         */
        void SetDllPathW(String format, int args);
    }
    /**
     * 封装一个静态方法,方便调用
     */
    public static void exec() {
        new DmRegHandler().handler();
    }
    public void handler() {
        //获取dm.dll的绝对路径。
        String absolutePath = FileUtil.getAbsolutePath("dm.dll");
        Console.log("大漠插件路径:{}", absolutePath);
        DmReg.INSTANCE.SetDllPathA(absolutePath, 0);
    }
}

再建一个大漠对象对应的接口

@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) {
        //调用免注册
        DmRegHandler.exec();
        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下。

 

 

 

 

 

posted on 2023-02-17 18:31  SunEn  阅读(441)  评论(0编辑  收藏  举报

导航