Springboot使用JNA访问C#生成的DLL方法总结

Springboot使用JNA访问C#生成的DLL方法总结

    • C#
    • C++
    • JAVA代码

入职一家新公司,面试前完全不知道是用C#开发的,也太底层了,JAVA开发的我,顿时觉得回到五年前,好多配置,一点也不轻便,感觉很笨重,组件全部是手写,但是还好,最底层的组件可以一直使用,就好比是JAVA的JPA组件一样,但是没办法了,已经入职了,由于要开发一个新系统,我不想写权限,也不想写C#,所以就研究了一下JAVA如何调用C#的方法。

在网上知道了有JNA这个组件后,就开始参考网上很多大神写的,让我研究了好几天,在这里做一个积累和总结。我用的是VisualStudio2019和Rider。

顺序是C#生成DLL----------》C++生成DLL----------》JAVA调用

之后的选择X64平台,需要根据自身的开发环境所调整,我的电脑和JDK均是64位

C#

创建一个类库DLL项目,这里不做过多解释,创建就可以了,我用的是Rider创建的,有兴趣的可以自行学习,这里不做介绍。

创建好之后如下图。
Springboot使用JNA访问C#生成的DLL方法总结_第1张图片
然后需要对类库进行设置,右键属性,

  1. 会有此页面,我这里由于版本太高,默认是4.7.2,所以需要修改成目标框架设置成4,根据自身坏境情况做修改。
  2. 点击程序集,选择弹出框的COM可见。
    Springboot使用JNA访问C#生成的DLL方法总结_第2张图片
  3. 点击生成选项,目标平台我这里是64,输出路径根据自身情况做调整,勾选选择COM互操作注册。
    Springboot使用JNA访问C#生成的DLL方法总结_第3张图片
  4. 在cs文件中写你需要的测试方法,这里就不过多写了,最基础的代码。
    强调一下,方法名跟什么大小写,下划线_都没有任何关系,我在别的文章中看到过,这里做一下解释,只要方法名能对应上即可
    Springboot使用JNA访问C#生成的DLL方法总结_第4张图片

记得要保存!
最后一步,右键生成DLL,生成的位置就是上图的输出路径位置。
这第一阶段的C#就好了。

C++

右键解决方案,添加新项目,Windows桌面向导
Springboot使用JNA访问C#生成的DLL方法总结_第5张图片
就会出现Project1,项目名可以自定义,这里不解释了。
Springboot使用JNA访问C#生成的DLL方法总结_第6张图片
右键属性,这里的平台设置需要和之前的C#的目标平台设置一致,在高级中找到公共语言,选择/clr的就可以,老版本开发工具不在高级里,在常规选项里,多留意一下。
Springboot使用JNA访问C#生成的DLL方法总结_第7张图片
继续选择C/C++语言,将符合模式选成否,应该是生成是报错,所以这里需要设置一下,回忆不起来了。
Springboot使用JNA访问C#生成的DLL方法总结_第8张图片
这一套设置完以后,可以开始写代码了。

  1. 先引用C#的DLL,右键添加引用即可。 Springboot使用JNA访问C#生成的DLL方法总结_第9张图片
  2. 在源文件上右键添加新项
    这里也可以将之后源文件的代码分开成一个头文件,由于我是初级学C的,就不这么麻烦,直接在cpp中完成了,不再单独引用头文件
    Springboot使用JNA访问C#生成的DLL方法总结_第10张图片
  3. 写cpp代码内容。
#ifdef AKL_API
#else
#define AKL_API extern "C" _declspec(dllimport) //交给客户端使用时
#endif

//这里就是对外的JAVA可访问的接口,和大小写,下划线没有任何关系,一致就行
AKL_API int GETADD(int a); //添加函数声明
AKL_API char* getStringInfo(char* str);

//如果这里报错,就说明没有正确引用C#的DLL,看是不是环境问题,一定要注意。
using namespace System;
using namespace ClassLibrary1;

int GETADD(int a)
{
    Class1^ method = gcnew Class1();
    int result = method->getAddInt(a);
    return result;
}

char* getStringInfo(char* str)
{
    String^ paraStr = gcnew String(str);
    Class1^ method = gcnew Class1();
    String^ resultString = method->getStringInfo(paraStr);
    char* result = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(resultString);
    return result;
}

最后将C++生成DLL。

JAVA代码

JAVA相对来说就很简单了,需要引入JNA的maven包。


       net.java.dev.jna
       jna
       5.5.0

--------------两个引用一个就可以,5.5.0版本的会提示方法过时,所以我用的是4.1.0-----------

       net.java.dev.jna
       jna
       4.1.0

将C++的DLL文件放在resources目录下
Springboot使用JNA访问C#生成的DLL方法总结_第11张图片
然后将C#的DLL文件放在JDK的bin路径下
Springboot使用JNA访问C#生成的DLL方法总结_第12张图片

public interface JNATest extends Library {
    JNATest INSTANCE  = (JNATest) Native.loadLibrary("Project1", JNATest.class);

	//C++刚才对外的接口名称,需要一致
    int GETADD(int a);
    String getStringInfo(String a);

}
   //导入不导入都可以,不导入直接使用JNATest.INSTANCE
    @Autowired
    private static JNATest jnaTest;

    public static void main(String[] args) {
        JNATest clib = jnaTest.INSTANCE;
        String resStr = clib.getStringInfo("Akl:Hello!");
        System.out.println(resStr);
        int resCal = clib.GETADD(101);
        System.out.println(resCal);
    }

控制台就可以输出了
Springboot使用JNA访问C#生成的DLL方法总结_第13张图片

你可能感兴趣的:(JNA,springboot,DLL,c#,c++,java)