qt和vs编译动态链接库dll,java调用

在很多场景中,需要用java来调用c++动态链接库,在windows中是.dll文件,linux中是.so文件,本篇介绍使用qt或vs编译动态链接库后,java调用的示例,以windows平台为例。

1.qt编译dll

1.1开发环境

qt5.12.9

1.2.新建项目

打开Qt Creator,文件->新建文件或项目,选择library->c++ Library

输入项目的名称,然后一直下一步,默认的就行,到Kits选择时,需要注意,你是准备在32位平台上跑,还是在64位平台上跑,这很重要,或者你两个版本都需要,选择相应的编译器。此处我选择了2个,两个版本都编译一个,后面有坑。

 

 其他默认下一步,项目建好后,默认有4个文件:项目文件1,头文件2个,源文件1个。

 

我们主要关心firstdll.h和first.cpp即可。下面实现一个加法函数如下,首先在头文件中声明,注意1.要把声明写在类的外面,写里面不行;注意2.要在声明中加上extern "C" 关键字,当java调用时,告诉程序,下面的函数要用C语言来编译了,其实就是一种约定

完整头文件firstdll.h如下

#ifndef FIRSTDLL_H
#define FIRSTDLL_H

#include "firstDll_global.h"

class FIRSTDLL_EXPORT FirstDll
{
public:
    FirstDll();
};

#endif // FIRSTDLL_H

extern "C"{
int sum(int a,int b);
}

然后来写源文件,即函数的实现,注意函数前要加上Q_DECL_EXPORT关键字,告诉程序,要把这个函数导出到链接库里。在这个函数里,我不仅实现了加法,还打印了结果,完整的firstdll.cpp如下

#include "testdll.h"
#include<iostream>
using namespace std;

TestDll::TestDll()
{
}

Q_DECL_EXPORT int sum(int a,int b)
{
    cout<<"a+b="<<a+b<<endl;
    return a+b;
}

好了,设置一下项目的构建路径,先采用release模式编译

 

 点击构建,编译输出显示正常退出,找到你刚刚设置的目录,看到有3个文件,dll就是动态链接库了

2.java调用dll

这里使用jna调用dll,先在maven中添加包依赖

 <dependency>
      <groupId>net.java.dev.jna</groupId>
      <artifactId>jna</artifactId>
      <version>5.12.1</version>
 </dependency>

 新建一个类,类中新建一个接口继承Library类,接口中使用Native.load方法先加载dll,该方法第1个参数是dll的绝对路径,第2个参数是接口的类名,作用就是把dll和这个接口连接起来。然后再实现dll中的函数,需要注意的是C语言中的类型和java中的类型是不一样的,官方给出了一个映射表,例如c++中int映射到Java中的int,c++中的char*映射到java中String,其他还有更复杂的请另行查找学习,实现代码如下

import com.sun.jna.Library;
import com.sun.jna.Native;

public class testJna {
    public interface Mydll extends Library{

        //加载dll
        Mydll mydll=(Mydll) Native.load("D:\\QtWorkSpace\\testDll\\release\\testDll.dll",Mydll.class);
        
        //实现dll中的函数
        int sum(int a,int b);

    }
}

接下来写一个main函数直接调用,代码如下

public static void main(String[] args){

        System.out.println(Mydll.mydll.sum(1,2));
    }

看一下结果

a+b=3
3

 第1行,a+b=3是dll中的函数打印的结果,第2行,3是调用dll函数java打印的返回值。

3.异常排除

3.1环境变量缺失

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'D:\QtWorkSpace\testDll\release\testDll.dll':
%1 不是有效的 Win32 应用程序。

%1 不是有效的 Win32 应用程序。
Native library (win32-x86-64/D:\QtWorkSpace\testDll\release\testDll.dll) not found in resource path 

Suppressed: java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序。

遇到这种错显示动态库加不进来,查看你的dll是否依赖于不在系统变量中的dll,举个例字,你的dll使用cout来打印文字,引用的iostream库,编译后的dll他只有你导出的函数,并不包含这个iostream,当dll运行的时候,还是要去系统中找这个依赖的,这里的依赖是libstdc++-6.dll,巧了你的系统中有个libstdc++-6.dll,但他是32位的,与你编译的64位的不兼容,就报错。归根到底是系统中没有正确的库,那这个库在哪呢?在你的编译器的lib里,而这个库你没有添加到环境变量里,就不能加载了。

解决方案:

1.缺什么库就添加什么库,一般你用qt编译的,库就在编译器的lib下面,我的目录就是E:\Qt\Qt5.12.9\Tools\mingw730_64\x86_64-w64-mingw32\lib,把这个目录添加到path环境变量中,重启IDE生效,再运行一次,加载dll的时候,就会到这个lib下面找到所需要的依赖,就可以正常运行了。

2.你的dll本身就是32位的与你的64位的jdk不一致,需要两者保持一致。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值