Java 调用C++/C#编写的Dll

  • 工具及环境
  • C++/C#
  • Java
  • 创建Javafx项目
  • Java调用C++编写的Dll
  • C++编写Dll
  • Java编写调用Dll
  • Java调用C#编写的Dll
  • C#编写Dll
  • Java编写调用Dll
  • JavaFx项目中使用
  • 搞定


工具及环境

C++/C#

  1. C++/C# : Visual Studio 2019
  2. .NET Framework 4.7.2

Java

  1. Java : IntelliJ IDEA 2021.1.2 x64
  2. Java版本:JDK11
  3. spring boot :2.5.13
  4. JNA :net.java.dev.jna 5.12.1
  5. jacob :1.18

创建Javafx项目

  1. 使用springboot2.5.13 + javafx 创建项目
  2. pom中添加javafx配置、jna、jacob
  • 对应处理关系
  • jna >> C++
  • jacob >> C#
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>javafx_dll</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>javafx_dll</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
        <org.openjfx>18.0.1</org.openjfx>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

		<!-- openjfx 👇 -->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-base</artifactId>
            <version>${org.openjfx}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${org.openjfx}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>${org.openjfx}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${org.openjfx}</version>
        </dependency>
		<!-- openjfx 👆 -->
		
        <!-- jna 👇 -->
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.12.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform -->
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna-platform</artifactId>
            <version>5.12.1</version>
        </dependency>
 		<!-- jna 👆 -->

         <!-- jacob👇 -->
        <dependency>
            <groupId>com.hynnet</groupId>
            <artifactId>jacob</artifactId>
            <version>1.18</version>
        </dependency>
		<!-- jacob 👆 -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  1. 创建javafx页面
  • JavafxDllApplication
package com.example.dll;

import javafx.application.Application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JavafxDllApplication {

    public static void main(String[] args) {
        SpringApplication.run(JavafxDllApplication.class, args);

        Application.launch(MainApp_001_menu.class);
    }

}
  • MainApp_001_menu
package com.example.dll;

import ch.qos.logback.core.Layout;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import javax.swing.*;


/**
 * Created by caoyang on 2022-06-30
 **/

public class MainApp_001_menu extends Application {

    @Override
    public void start(Stage primaryStage) {

        VBox vBox = new VBox();
        vBox.setStyle("-fx-background-color:#ffffff");

        MenuBar mb = new MenuBar();
        Menu menu1 = new Menu("DLL调用");
        Menu menu2 = new Menu("其他");

        ImageView iv1 = new ImageView("icon/logo.png");
        iv1.setFitWidth(20);
        iv1.setFitHeight(20);
        MenuItem menuitem1 = new MenuItem("调用C++>dll", iv1);
        MenuItem menuitem2 = new MenuItem("调用C#>dll");
        menu1.getItems().addAll(menuitem1, menuitem2);

        MenuItem menuitem4 = new MenuItem("关于");
        menu2.getItems().addAll(menuitem4);

        mb.getMenus().addAll(menu1, menu2);
        vBox.getChildren().add(mb);

        //为menuitem1添加快捷键操作
        menuitem1.setAccelerator(KeyCombination.valueOf("ctrl+alt+m"));
        menuitem1.setAccelerator(KeyCombination.valueOf("ctrl+alt+n"));

        Scene scene = new Scene(vBox);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Java调用DLL的使用");
        primaryStage.getIcons().add(new Image("icon/logo.png"));
        primaryStage.setWidth(500);
        primaryStage.setHeight(400);
        primaryStage.show();


        Label label_1 = new Label("调用结果展示:");
        Label label_2 = new Label("");
        HBox hb = new HBox();
        hb.getChildren().addAll(label_1, label_2);
        BorderPane borderPane = new BorderPane();
        borderPane.setCenter(hb);
        vBox.getChildren().add(borderPane);


        //初始化工具栏的宽度与父窗口一致
        mb.setPrefWidth(vBox.getWidth());
        //监听窗口宽度属性值的变化
        vBox.widthProperty().addListener(new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> arg0, Number oldValue, Number newValue) {
                //设置工具栏的宽度与父窗口一致
//				mb.setPrefWidth(primaryStage.getWidth());
                mb.setPrefWidth(newValue.doubleValue());
            }
        });

        //新建菜单添加事件
        menuitem1.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                System.out.println("C++>Dll");
                # TODO
            }
        });

        menuitem2.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                System.out.println("C#>Dll");
                # TODO
            }
        });


    }


}
  1. 运行效果

Java调用C++编写的Dll

C++编写Dll

  1. 创建:动态链接库(DLL)
  2. springboot dll文件放在哪 springboot调用dll_c#


  3. springboot dll文件放在哪 springboot调用dll_c#_02

  4. 进入项目编辑:
  • 源文件》TestDll.cpp
  • 头文件》TestDll.h
  1. 设置为64位
  2. 生成DLL文件

Java编写调用Dll

  1. 将上节生成的DLL文件拷贝至resources文件夹中
  2. springboot dll文件放在哪 springboot调用dll_c#_03


  3. 创建接口MyTestDll
package com.example.dll;

import com.sun.jna.Library;
import com.sun.jna.Native;

/**
 * Created by caoyang on 2022-08-08
 **/
public interface MyTestDll extends Library {
    // 反射实例化
    MyTestDll dll = (MyTestDll) Native.load("TestDll", MyTestDll.class);
    int add(int a, int b); //覆写 DLL 中的方法
}
  1. 测试调用
package com.example.dll;

/**
 * Created by caoyang on 2022-08-08
 * 测试:Java调用C++生成的DLL
 **/
public class TestDll {
    public static void main(String[] args) {
//        System.out.println(Platform.isWindows());
        System.setProperty("jna.encoding", "GBK");
        // 接口中方法的调用
        System.out.println(MyTestDll.dll.add(1, 3)); 
    }
}
  1. 运行效果
  2. springboot dll文件放在哪 springboot调用dll_c#_04


Java调用C#编写的Dll

C#编写Dll

  1. 创建项目:类库(.net Frameword)
  2. springboot dll文件放在哪 springboot调用dll_c++_05


  3. springboot dll文件放在哪 springboot调用dll_springboot dll文件放在哪_06

  4. 创建方法
  5. springboot dll文件放在哪 springboot调用dll_springboot dll文件放在哪_07

  6. 设置为64位
  7. springboot dll文件放在哪 springboot调用dll_Java_08


  8. springboot dll文件放在哪 springboot调用dll_springboot dll文件放在哪_09


  9. springboot dll文件放在哪 springboot调用dll_springboot dll文件放在哪_10

  10. 属性配置
  11. springboot dll文件放在哪 springboot调用dll_c#_11


  12. springboot dll文件放在哪 springboot调用dll_c++_12


  13. springboot dll文件放在哪 springboot调用dll_c#_13

  14. 生成DLL
  15. springboot dll文件放在哪 springboot调用dll_c++_14


  16. springboot dll文件放在哪 springboot调用dll_c++_15

  17. 生成时出现问题记录
    问题:Visual Studio编译报“无法注册程序集dll- 拒绝访问。请确保您正在以管理员身份运行应用程序。对注册表项”“的访问被拒绝。”
    处理:WIN+R,运行对话框中输入gpedit.msc,开启组策略,然后一步步地在“计算机配置”-“Windows 设置”-“安全设置”-“本地策略”-“安全选项”,找到右侧的
    “用户账户控制:以管理员批准模式运行所有管理员”这个项,你会看到这个项默认是启用的,把它设成禁用。
  18. springboot dll文件放在哪 springboot调用dll_Java_16

Java编写调用Dll

  1. 下载 jacob-1.18-x64.dll,并将其放置在电脑的 “C:\Windows\System32”目录中。
    下载地址:https://github.com/freemansoft/jacob-project/releases/tag/Root_B-1_18
  2. 上述javafx项目中编写测试代码
package com.example.dll;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

/**
 * Created by caoyang on 2022-08-09
 * 测试:Java调用C#生成的DLL   .NET Framework 4.7.2
 **/
public class TestNetDll {

    public static void main(String[] args) {
        TestNetDll t = new TestNetDll();
        t.add(5, 6);
    }
	
    public String add(int a, int b){
        try {
            ActiveXComponent dotnetCom = null;
            dotnetCom = new ActiveXComponent("Java_Net.Class1");
            Variant var = Dispatch.call(dotnetCom, "add", a, b);
            String str = var.toString(); //返回值
            System.out.println(str);
            return str;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
}
  1. 运行效果
  2. springboot dll文件放在哪 springboot调用dll_java_17


JavaFx项目中使用

  1. 在Javafx项目中增加调用代码
/**
 * Created by caoyang on 2022-06-30
 **/

public class MainApp_001_menu extends Application {

    @Override
    public void start(Stage primaryStage) {

        // 原有代码,略。。。。
		// 在下面两个方法中创建调用
        //新建菜单添加事件
        menuitem1.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                System.out.println("C++>Dll");
                int val = MyTestDll.dll.add(1, 3);
                label_2.setText("C++>Dll:"+String.valueOf(val));
            }
        });

        menuitem2.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                System.out.println("C#>Dll");
                TestNetDll testNetDll = new TestNetDll();
                String val = testNetDll.add(5,6);
                label_2.setText("C#>Dll:"+String.valueOf(val));
            }
        });


    }


}

搞定

springboot dll文件放在哪 springboot调用dll_c#_18


springboot dll文件放在哪 springboot调用dll_springboot dll文件放在哪_19