zoukankan      html  css  js  c++  java
  • 【开发者笔记】java 利用jna调用c#的dll

    【开发者笔记】java 利用jna调用c#的dll

     
     https://www.cnblogs.com/wyongbo/p/jnaTest.html
     

    一、需求阐述:

      如果我们的项目利用c#开发,到了开发后期需要和java组进行合作,其中有一部分业务逻辑利用c#已经code completed,那么我们可能会考虑用java来调用现成的c#dll实现需求。前几天工作上正好遇到这样一个问题,于是记下开发过程。

      当然这只是个假设,具体情况具体分析,个人认为重构代码才是王道……

    二、原理说明:

      其实具体原理我也没弄太明白,我就根据自己的理解来说吧,抛砖引玉。

      因为c#代码是托管到.net平台上的,所以java不能直接调用c#代码,于是引入C++中间件,c++项目可以设置项目为clr公共运行时,从而通过引用的方式调用c#相应方法。而jna是可以直接调用c++生成的dll的,于是大致流程就走通了。c++调用写好的c#dll,java再调用c++生成的dll中间件,大致流程就是这样了,不过其中有很多坑,下面我会细说。

    三、运行平台:

      系统:Windows 10 x64

      开发工具:Visual Studio 2015/2017(我笔记本和公司电脑安装不同版本,我都有实现过)   MyEclipse2014   

      SDK:jdk-x86、jdk-x64 (dll分为x86和x64平台,和jdk的版本要对应,同一台电脑装两个版本的jdk比较烦,我采用的是系统配置jdk32位调试32位dll,然后myeclipse自带64位jdk调试64位dll)

    四、准备工作:

      1、首先准备上述运行平台,建议选择和系统位数一致的jdk(安装vs、myeclipse或eclipse或sts);

      2、下载jna.jar :JNA下载(下载jna-4.4.0.jar 和 jna-platform-4.4.0)

    五、开始CODE

      5.1 生成c#DLL

        5.1.1 以管理员方式启动vs(项目涉及到注册com组件,必须以管理员启动才能完成),新建c#项目

      

        5.1.2 设置c#项目

          首先,右键刚刚新建的Invoke项目,点击属性。

             继续设置项目属性。

             记得保存。

             然后新建需要被调用的CSharp类代码。这里我们新建一些简单的方法,为了演示效果我们分别对int、string、bool进行操作。如图:

            然后右键项目,点击生成。

            第一步,完成,干得漂亮。

      5.2 生成c++中间件

        5.2.1 新建c++项目并设置属性

          

          项目新建成功,右键项目,选择属性。

      

      

        5.2.2 书写c++代码

          添加cpp文件

          

          

               编辑cpp文件

            

          好了,c++和c#全部工作完成,右键生成。

          复制下dll生成文件全名,一会儿java里面用。

    六、编写java代码

      6.1 新建java project ,注意选择和dll平台一致的jdk。然后将之前下载的两个jna的jar加载到项目里面,如图:

      6.2  开始写java 代码

      然后我们运行:

          哦豁,报错了【无效的内存访问】,因为java找到了c++dll,但是没找到c#的dll,其中c++dll我们写的全路径名,可以直接找到,那么c#的dll怎么找呢。答案是将c#的dll复制到jdk的bin目录下,jvm就能找到了。

          如图我们将Invoke.dll复制到jdk的bin目录下:

      

          然后再运行:

        

          nice!对于常用类型中的int、string、boolean都可以顺利传递了,事实上其他类型的也可以实现,只要遵循不同语言之间的类型对应关系就可以了,具体的类型关系可以百度。

        

    七、注意事项

      7.1 java报错:Exception in thread "main" java.lang.Error: Invalid memory access

        可能原因:

          1、c#dll没有复制到jdk的bin目录;

          2、java和c++之间数据类型不对应;

      7.1.2 java报错:Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'D:vs workplaceX86InvokeTestReleaseX86CPPDlls': Native library (win32-x86/D:vs workplaceX86InvokeTestReleaseX86CPPDlls.dll) not found in resource path ([file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/bin/, file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-4.4.0.jar, file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-platform-4.4.0.jar])

        可能原因:

          1、c++dll路径不正确,建议做test时用绝对路径,这样你在c++项目编译过后不用拷贝便可以在java程序里面直接调用;

          2、jdk的平台和c++项目的平台不匹配,jdk是32位那么c++dll一定也是32位的,64位也同样;

      7.1.3 windows64位下编译的32位dll测试失败,暂时不清楚是不是64位系统的原因,由于我电脑虚拟机没有装上,就没有去32位系统上测试了。

    ================================2018-1-3 17:15:54 更新========================================================

    1、提供给测试项目开源地址:

        Github测试代码连接

        Github测试代码连接2

    2、怎么确定c#的dll是不是成功复制到jdk的bin目录呢?换言之怎么确定自己的bin目录在哪里呢?可以在eclipse中运行的时候通过控制台看到。

    黑夜给了我黑色的眼睛,我却用它寻找光明
  • 相关阅读:
    6-Python爬虫-分布式爬虫/Redis
    ES 查询时 排序报错(fielddata is disabled on text fileds by default ... )解决方法
    Intellij Idea webstorm 激活
    Intellij Idea 配置jdk
    java 获取(格式化)日期格式
    js 跳转 XSS漏洞 预防
    CSS去掉背景颜色
    js对象无法当成参数传递 解决方法
    Elasticsearch java api
    java多条件查询SQL语句拼接的小技巧
  • 原文地址:https://www.cnblogs.com/handsome1013/p/9361114.html
Copyright © 2011-2022 走看看