jar包转dll后引入C#项目进行调用(2021.3.31)

前提环境

        Windows7 64位操作系统,已安装Java 1.8Visual Studio 2015


1、jar包简介

        jar包本质上就是多个文件夹下的多个class文件(须有一个main函数)、一些外部依赖包和jar包描述信息文件组成的以.jar为后缀名格式的压缩包,它可以用WinRAR压缩文件管理器打开并查看,MANIFEST文件对于jar打包都是必须的。

jar包结构示意图及理解
        MANIFEST.MF文件描述了打包后的jar文件的详细信息,存在于打包后的META-INF 的文件夹.一个简单的MANIFEST.MF文件主要内容如下:

        MANIFEST.MF文件主要就是Manifest-VersionMain-ClassClass-Path这三个属性在制作jar包时非常重要.Manifest-Version 是版本号,照着写就行。Main-Class则是jar包的入口程序,指定运行的类的全称(一定要包含包名),这样可以使用java -jar name.jar命令直接运行jar包。第三个Class-Path是指的打包时需要依赖的其他jar包,打包的时候自己的程序中也可能含有其他的jar包所以要添加依赖。注意:(每个MANIFEST属性冒号与内容之间都有一个空格,并且写完后最后还要留有一行空行,不然运行时还是出现找不到主清单属性的错误

2、jar包生成(.java源文件 -> .class字节码文件 -> .jar包)

2.1 利用Eclipse新建Java工程导出jar包

        这里下载最新免安装(解压版的)Eclipse中的eclipse-java-2021-03-R-win32-x86_64.zip,用WinRAR解压后放到D盘,在eclipse文件夹下新建工作空间workspace文件夹,然后双击eclipse文件夹下的eclipse.exe将工作空间选为D:\eclipse-java-2021-03-R-win32-x86_64\eclipse\workspace

在这里插入图片描述


在这里插入图片描述
        打开Eclipse,点击左上角的File->New->Java Project,新建Java工程,Project name设置为JavaTestGenerateJar


        之后在JavaTestGenerateJar项目下的src上点击鼠标右键新建两个package包testgenerate,并分别在包test和generate中新建JieCheng类和HelloWorld类。
在这里插入图片描述
        JieCheng.java

package generate;

public class JieCheng 
{
    
    
	public int n=0;//公有成员变量
	
	public JieCheng(int n)//自定义构造函数
	{
    
    
		this.n = n;
	}
	
	public int Result()//计算阶乘的函数
	{
    
    
		int result;
		if(this.n <0)
			result = -1;
		else if(this.n == 0 || this.n == 1)
		{
    
    
			result =1;
		}
		else
		{
    
    
			result = 1;
			for(int i=0;i<this.n;i++)
			{
    
    
				if( i==0)
					result *= 1;
				else
					result *=(i+1);
			}
		}
		return result;
	}
}

        HelloWorld.java

package test;
import generate.JieCheng;

public class HelloWorld 
{
    
    
	public static void main(String[] args)
	{
    
    
		int n = 10;
		for(int i=0;i<=n;i++) {
    
    
			JieCheng jc = new JieCheng(i);
			System.out.println(i+"! = "+jc.Result());
		}
	}
}

        代码编写完成后,在JavaTestGenerateJar项目上右键选择Properties后打开属性窗口,选中Enable project specific settings,并选择JDK Compiler compliance level为1.8,最后点击Apply即可。
在这里插入图片描述
        在HelloWorld.java代码中右键选择Run as->Java Application运行Java工程,在Console控制台中可以看到正确的输出结果。
在这里插入图片描述
在这里插入图片描述
        同时在JavaTestGenerateJar工程的bin(二进制binary的简称)目录下可以看到对应包里都生成了类编译后的.class文件(generate->JieCheng.class和test->HelloWorld.Class)
在这里插入图片描述
在这里插入图片描述
        在JavaTestGenerateJar项目上右键鼠标选择Export后打开Export窗口,选择Java下的JAR file后点击next,
在这里插入图片描述

        在弹出的JAR Export窗口中,选中JavaTestGenerateJar项目下src中所有的包,之后选择输出路径和Jar包的名称后,点击Finish后即可在项目文件夹下看到导出的JavaTestGenerateJar.jar包了。

在这里插入图片描述

        Win+R在导出Jar包文件夹下打开cmd窗口输入如下命令来测试打包后的Jar包是否能够成功运行。

java -jar JavaTestGenerateJar.jar

        运行java -jar JavaTestGenerateJar.jar命令后会提示JavaTestGenerateJar.jar中没有主清单属性,可通过以下方法解决:在JavaTestGenerateJar.jar文件上右键选择用WinRAR打开,进入META-INF文件夹后用记事本打开MANIFEST.MF文件,并在里面添加一行内容: Main-Class: test.HelloWorld后保存。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3、jar包转dll(使用IKVM)

        jar包转DLL需要使用IKVM工具,下面简单介绍一下IKVM.NET及其配置,并利用IKVM工具来实现jar包到DLL的转换。

3.1 IKVM.NET简介

        jar包要想转换成为dlll,可以借助一款常用工具:IKVM.NET,IKVM.NET是在Jeroen Frijters着手创建一种将现有Java数据库应用程序迁移到.NET的方法时创建的。IKVM.NET使得既可以用Java开发.NET应用程序,又可以在以任何.NET语言编写的应用程序中使用现有的Java API和库。
在这里插入图片描述        使用IKVM.NET的主要方法有两种:动态静态
        动态:在这种模式下,Java类和jar被直接用于在.NET运行时上执行Java应用程序。Java字节码可以即时转换为CIL,无需其他步骤。此模式支持完整的Java类加载器模型。
        静态:为了允许.NET应用程序使用Java代码,必须将其编译为DLL并直接使用。字节码将转换为CIL并以这种形式存储。程序集可以由.NET应用程序直接引用,并且可以将Java对象用作.NET对象。尽管静态模式不支持完整的Java类加载器机制,但是静态编译的代码可以创建类加载器并动态加载类。

3.2 下载并配置IKVM.NET (注意要与JDK版本一致)

        IKVM.NET的源码和二进制分布程序可以前往SourceForget下载ikvmbin-7.2.4630.5.zip压缩包(好像适用于Java 7)
在这里插入图片描述
        而由于我使用的是Java 8(Java 1.8.0_281),则需要下载8.x版本的IKVM:http://www.frijters.net/ikvmbin-8.1.5717.0.zip
在这里插入图片描述
在这里插入图片描述
        解压到D盘后ikvmbin-8.1.5717.0文件夹内容如下图所示:

        下面在计算机上点击鼠标右键,选择属性->高级系统设置->环境变量找到Path后,在最后添加D:\ikvm-8.1.5717.0\bin

在这里插入图片描述
        然后Win+R打开cmd命令行窗口,输入ikvm测试环境变量是否配置成功,成功后如下图所示。

3.3 使用IKVM将jar包转为DLL

        IKVM版本要与JDK版本一致,JDK1.8应该配置IKVM8.0以上的。具体使用IKVM将jar包转DLL的流程可以参考IKVM.NET的Wiki帮助中的Convert_a_jar_file_to_a_dll_and_use_it_as_library,现在找到要转为DLL的Jar包,在目录下打开cmd窗口,输入命令:ikvmc JavaTestGenerateJar.jar -out:HelloWorld.dll后,结果看到在文件夹下生成了HelloWorld.dll文件,转换成功。(命令格式为ikvmc JARPackage.jar -out:DLLName.dll
在这里插入图片描述

4、C#调用dll

4.1 VS新建C#项目

        打开Visual Studio 2015,新建C#->Windows->控制台应用程序,输入项目名称TestDLLByJarExport,选择项目保存路径后点击确定。
在这里插入图片描述
        在打开的Program.cs的Main函数中添加一行控制台输出Hello World!的代码,然后点击菜单栏中的调试->开始执行(不调试)测试运行。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestDLLByJarExport
{
    
    
    class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            Console.WriteLine("Hello World!");//添加一行控制台输出Hello World!代码
        }
    }
}

        运行后控制台输出结果正常,如下图所示:
在这里插入图片描述

4.2 C#项目中对jar包转换后的dll添加引用

        首先复制D:\ikvm-8.1.5717.0\bin目录下所有dll文件

        然后将上述复制的dll文件都粘贴到D:\Visual Studio 2015\MyProjects\TestDLLByJarExport\TestDLLByJarExport\bin\Debug目录下
在这里插入图片描述
        同时将3.3中jar包转换后的dll文件HelloWorld.dll复制到该目录下

在这里插入图片描述
        在Visual Studio 2015的TestDLLByJarExport项目的引用上右键点击添加引用,在弹出的引用管理器中点击底部的浏览按钮,选择项目的bin\Debug下所有的dll后点击添加会返回到引用管理器窗口,再点击确定即可。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
        可以看到,添加引用后,HelloWorld.dll以及IKVM相关的dll都被添加到项目的引用下。
在这里插入图片描述

4.3 C#项目中添加调用dll代码

在这里插入图片描述
        在TestDLLByJarExport项目的Program.cs中添加调用dll的相关代码时,需要首先添加库 using 包名; 同时直接在程序中调用类中方法即可generate.JieCheng jc = new JieCheng(i); Console.WriteLine(i+"! = "+(jc.Result()).ToString());

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using generate;//using 包名

namespace TestDLLByJarExport
{
    
    
    class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            Console.WriteLine("Hello World!");//添加一行控制台输出Hello World!代码
            //以下为调用HelloWorld.dll封装的generate包下的JieCheng类中的Result()方法的具体代码
            for(int i=0;i<=10;i++)
            {
    
    
                generate.JieCheng jc = new JieCheng(i);
                Console.WriteLine(i+"! = "+(jc.Result()).ToString());
            }
        }
    }
}

        最后调用HelloWorld.dll中generate包下的JieCheng类中的Result()方法后的运行结果如下图所示:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/jing_zhong/article/details/115326602
今日推荐