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#
- C++/C# : Visual Studio 2019
- .NET Framework 4.7.2
Java
- Java : IntelliJ IDEA 2021.1.2 x64
- Java版本:JDK11
- spring boot :2.5.13
- JNA :net.java.dev.jna 5.12.1
- jacob :1.18
创建Javafx项目
- 使用springboot2.5.13 + javafx 创建项目
- 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>
- 创建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
}
});
}
}
- 运行效果
Java调用C++编写的Dll
C++编写Dll
- 创建:动态链接库(DLL)
- 进入项目编辑:
- 源文件》TestDll.cpp
- 头文件》TestDll.h
- 设置为64位
- 生成DLL文件
Java编写调用Dll
- 将上节生成的DLL文件拷贝至resources文件夹中
- 创建接口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 中的方法
}
测试调用
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));
}
}
- 运行效果
Java调用C#编写的Dll
C#编写Dll
- 创建项目:类库(.net Frameword)
- 创建方法
- 设置为64位
- 属性配置
- 生成DLL
- 生成时出现问题记录
问题:Visual Studio编译报“无法注册程序集dll- 拒绝访问。请确保您正在以管理员身份运行应用程序。对注册表项”“的访问被拒绝。”
处理:WIN+R,运行对话框中输入gpedit.msc,开启组策略,然后一步步地在“计算机配置”-“Windows 设置”-“安全设置”-“本地策略”-“安全选项”,找到右侧的
“用户账户控制:以管理员批准模式运行所有管理员”这个项,你会看到这个项默认是启用的,把它设成禁用。
Java编写调用Dll
- 下载 jacob-1.18-x64.dll,并将其放置在电脑的 “C:\Windows\System32”目录中。
下载地址:https://github.com/freemansoft/jacob-project/releases/tag/Root_B-1_18 - 上述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;
}
}
}
- 运行效果
JavaFx项目中使用
- 在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));
}
});
}
}
搞定