因原文,有些点讲的不是非常的清楚,本人C#以及C#开发工具VS也不是非常的熟悉。因此坑了一下午,下面记录一下遇到的一些坑。
一、环境
开发工具:Visual Studio2019、Eclipse
SDK:jdk8-x64
二、准备工作
JNA下载 提取码: wd6v
三、入坑
- 生成C#DLL
1.1启动VS创建C#项目(这里注意是创建.NET Framework类库) - 1.2设置c#项目
- 这里记得保存,C#比较坑关闭时不提示你保存。
1.3来编写我们需要调用的类 - 然后在项目上点击右键,点击生成就会看见下面的结果。
- 第一步已经顺利完成了,接下来我们开始第二步
- 生成c++DLL
好家伙这里坑了我一下午,下面来记录一下。
这里已经安装了VS,但是再次打开VS安装包会看见下面的图片效果 - 点击修改
- 下面划重点,这里一定要勾选(默认是不勾选的)。不勾选的话下面的步骤就不用看了(此处坑了一下午)。
- 接下来我们创建C++项目
右键“解决方案”,新建项目 - 此处上面如果不勾选的话是建不了CLR项目的
- 接下来设置属性
- 接下来引用我们上面写的项目(右键引用)
- 添加cpp文件(右键源文件)
- 编写新建的cpp文件
#ifdef MYLIBAPI
#else
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
MYLIBAPI char* getName(char* name);//添加函数声明
MYLIBAPI int getAge(int age);
using namespace System; // 如果不建CLR项目此处引用会报错
using namespace JNATest;
char* getName(char* name)
{
String^ paraStr = gcnew String(name);
JNA^ jna = gcnew JNA(); // 注意此处是你写的C#类名
String^ resultString = jna -> getName(paraStr); // 此处是类里的方法名
char* result = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(resultString);
return result;
}
int getAge(int age)
{
JNA^ jna = gcnew JNA();
int result = jna -> getAge(age);
return result;
}
好了C#与C++项目都写完了,接下来右键生成
- 开始写Java代码(这里首先需要将上图倒数第三行路径下的DLL文件放入jdk的bin文件夹中)
package com.bjx.tex.equations;
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
*
* @author Christmas_G
* @date 2019-06-28 10:34:05
*
*/
public class Test {
interface JNALibrary extends Library {
JNALibrary INSTANCE = (JNALibrary) Native.loadLibrary("JNADll", JNALibrary.class);
/* 需要调用的方法,方法名与c++方法名相同 */
String getName(String value);
int getAge(int age);
}
public static void main(String[] args) throws Exception {
System.out.println(System.getProperty("java.version"));// 输出当前jdk版本号
System.out.println(System.getProperty("sun.arch.data.model"));// 输出当前jdk所用平台
String name = JNALibrary.INSTANCE.getName("小红");
int age = JNALibrary.INSTANCE.getAge(3);
System.out.println(name + "今年" + age + "岁");
}
}
运行结果