Java通过JNI4Net实现调用C#

写在前面,本文参考了网上另外一位大哥的文章,但是当我想挂链接的时候,却找不到了,如果看到了,可以联系本人,侵删!

一、背景

遇到了java调用C#类库的情况,在网上找了几种方法:jni4net、jna,最终选择了jni4net,可以全部打包在项目中。这里作为记录和分享给有用的朋友们。

1、jni4net介绍

jni4net是一个开源的框架,它允许Java和.NET应用程序相互调用对方的方法。这个框架利用了反射、JNI、代理和垃圾回收等技术来实现跨语言平台的互操作性。通过jni4net,开发者可以在.NET环境中调用Java类库,同样也可以在Java环境中调用.NET类库,从而实现跨语言平台的互操作性。

使用jni4net的基本步骤通常包括以下几个方面:

1. 准备和配置环境: 首先需要下载并安装jni4net框架,这通常可以从SourceForge等平台获取。安装后,需要配置环境变量,确保proxygen工具和相关的命令可以在命令行中直接使用。

2. 创建和编译C#或Java项目:在Visual Studio中创建C#类库项目,并编写相应的代码。编译后,使用proxygen工具来生成代理类,这样Java代码就可以调用C#编写的方法了。

3. 生成代理类 :使用proxygen工具来生成代理类,这是通过在命令行中执行相应的命令来完成的。例如,使用命令 .\proxygen.exe "DLL所在路径" -wd "java项目根路径" 来生成对应的Java类和JAR文件。

4. 打包和部署: 将生成的代理类和需要的DLL文件打包成JAR文件,并将其部署到Java项目中。这通常涉及到将JAR文件和DLL文件放到Java项目的特定目录下,并在项目配置中添加对应的依赖。

5. 编写Java代码进行调用:在Java代码中,通过jni4net提供的API来加载和注册C#编写的DLL,然后就可以像调用本地Java方法一样调用C#方法了。

6. 解决依赖问题: 如果使用的Java类或C#类有额外的依赖,可能需要使用-cp或dp参数来指定额外的类路径或依赖项。

通过这些步骤,开发者可以实现Java和.NET之间的互操作,使得跨平台的软件开发变得更加灵活和高效。需要注意的是,jni4net的使用可能会涉及到一些技术细节和潜在的兼容性问题,因此在实际使用时,建议仔细阅读官方文档和相关的教程,以确保正确和高效地使用这个框架。

二、工具

1、1.jni4net-0.8.8.0,提供下载

📎jni4net-0.8.8.0.zip

2、Visual Studio2022,请至官网下载

3、相关代码demo

📎project.zip java代码

📎HelloWorld.zip c#代码

三、编码

1、C#部分

1.1、新建项目

1.2、选择 类库(.NET Framework)

1.3、项目名称

1.4、重命名类名

1.5、完善执行方法

arduino 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    public class Hello
    {
        public static int display(int a, int b)
        {
            return a + b;
        }
    }
}

1.6、调整配置

1.7、生成dll

至此,C#生成dll部分完成

2、jni4net

2.1、解压工具包

压缩包解压至 D:\Tools\jni4net-0.8.8.0

2.2、.转换dll

生成c++和java 源码:

swift 复制代码
D:\Tools\jni4net-0.8.8.0\bin\proxygen.exe "D:\project\test\jni4net\HelloWorld.dll" -wd "D:\project\test\jni4net"

执行完毕的项目文件目录

2.3、生成jar

执行命令:build.cmd

bash 复制代码
#切换盘符
d:
#切换目录
cd D:\project\test\jni4net\
#执行命令
build.cmd

异常情况:

如果出现上面异常则是 没有配置Framework环境变量

文件管理器:C:\Windows\Microsoft.NET\Framework

选择4.x版本,记住目录路径,添加至环境变量 PATH

重新打开cmd 执行上面的命令:

至此dll转换完毕

3、JAVA部分

3.1、打开项目

3.2、复制jni4net相关库到项目

3.3、 maven项目,新建pom.xml

xml 复制代码
<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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.shr25</groupId>
  <artifactId>jni4net</artifactId>
  <version>1.0</version>
  <name>jni4net</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <skipTests>true</skipTests>
  </properties>
  <dependencies>
    <dependency>
      <groupId>com.xgtx</groupId>
      <artifactId>HelloWorld.j4n</artifactId>
      <version>1.0.1</version>
      <scope>system</scope>
      <systemPath>${project.basedir}/HelloWorld.j4n.jar</systemPath>
    </dependency>
    <dependency>
      <groupId>com.xgtx</groupId>
      <artifactId>jni4net.j</artifactId>
      <version>1.0.1</version>
      <scope>system</scope>
      <systemPath>${project.basedir}/jni4net.j-0.8.8.0.jar</systemPath>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>${project.name}</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

3.4、转换maven项目

3.5、新建测试类

arduino 复制代码
import helloworld.Hello;
import net.sf.jni4net.Bridge;
 
import java.io.File;
import java.io.IOException;
 
public class Test {
    public static void main(String[] args) throws IOException {
        Bridge.setVerbose(true);
        Bridge.init();
        File dll = new File(  "HelloWorld.j4n.dll");
        Bridge.LoadAndRegisterAssemblyFrom(dll);
        int result = Hello.display(66,22);
        System.out.println("计算结果为:"+result);
    }
}

3.6、运行结果

删除过程代码可以保留,只不过对项目没有意义,至此java调用c#案例完成。

相关推荐
StayInLove16 分钟前
G1垃圾回收器日志详解
java·开发语言
对许20 分钟前
SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“
java·log4j
无尽的大道24 分钟前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化
小鑫记得努力33 分钟前
Java类和对象(下篇)
java
binishuaio37 分钟前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE39 分钟前
【Java SE】StringBuffer
java·开发语言
老友@39 分钟前
aspose如何获取PPT放映页“切换”的“持续时间”值
java·powerpoint·aspose
wrx繁星点点1 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
Upaaui1 小时前
Aop+自定义注解实现数据字典映射
java
zzzgd8161 小时前
easyexcel实现自定义的策略类, 最后追加错误提示列, 自适应列宽,自动合并重复单元格, 美化表头
java·excel·表格·easyexcel·导入导出