使用PackageCompiler.jl编译动态链接库

1 创建项目文件

使用Pkg包创建项目文件,在命令行窗口运行julia,然后运行以下指令生成项文件夹libTest

using Pkg
Pkg.generate("libTest")

打开libTest/src/libTest.jl编写代码,如果没有libTest.jl文件,手动创建即可。

module libTest
Base.@ccallable function increment(count::Cint)::Cint
    count += 3
    println("Incremented count: $count (Cint)")
    return count
end
end # module libTest

2 编译运行

使用PackageCompiler.jlcreate_library函数即可编译成动态链接库。在libTest文件夹下创建脚本build.jl,内容如下:

using PackageCompiler

target_dir = get(ENV, "OUTDIR", "$(@__DIR__)/LibCompiled")
target_dir = replace(target_dir, "\\"=>"/")       # Change Windows paths to use "/"
println(target_dir)

println("Creating library in $target_dir")
PackageCompiler.create_library(".", target_dir;
                                lib_name="libTest",
                                incremental=false,
                                filter_stdlibs=true,
                                force=true, # Overwrite target_dir.
                                header_files = ["$(@__DIR__)/src/include/libTest.h"],
)

编译前需要手动创建libTest.h文件,否则编译报错。

int increment(int);

运行指令编译动态链接库

julia build.jl

3 使用c语言调用测试

libTest文件夹下创建test.c文件,然后编写测试程序,测试上述动态链接库是否能正常运行

#include <stdio.h>
#include "julia_init.h"
#include "libTest.h"

int main(int argc, char *argv[])
{
    init_julia(argc, argv);
    
    printf("julia动态库输出值:%d",increment(10));
    
    shutdown_julia(0);

    return 0;
}

使用gcc命令编译成功后,运行test.exe

gcc .\test.c -o .\LibCompiled\bin\test.exe  -L.\LibCompiled\bin\ -I.\LibCompiled\include -llibTest

如果test.exe输出正确,即证明动态联接库编译正确。

4 进阶

(1)调用第三方模块

如果调用第三方模块,需要进行声明。如调用Statistics,可在libTest文件夹下运行指令

julia -q --project

然后按下**]进入Pkg模式**,运行add指令添加Statistics

add Statistics

(2)调用自定义模块

调用自定义模块需要创建自定义模块project,如创建模块Test1,首先在“/src/module”文件夹下运行指令

julia -q --project

然后进入Pkg安装模式,运行generate(“Test1”)生成模块文件夹,修改/Test1/src/Test1.jl

添加自定义模块

在在libTest文件夹下运行指令“julia -q --project”,进入Pkg安装模式下运行

dev ./src/module/Test1

libTest.jl文件中添加语句

using Test

即可实现自定义模块加载。

注意: 如果自定义模块引用了第三方库,应在“/src/module/Test1文件夹下运行指令“julia -q --project”,进入Pkg安装模式下执行指令“add 第三方模块名”,
如果需要删除第三方模块,执行指令“rm 第三方模块名

(3)c语言与julia语言一般类型的对应关系

julia代码编译为动态链接库,需要保证数据类型准确对应,如:

序号C类型julia别名julia类型
1intCintInt32
2doubleCdoubleFloat64

在声明 julia c接口函数时,需要使用 julia别名

Base.@ccallable function increment(count::Cint)::Cint

(4)数组对应关系

c语言数组可采用 int a[3] 或指针 int *a的形式声明,此时 a 代表了数组的第一个元素的地址,julia语言中对应的形式为 Ptr{Cint}
将c语言数组传递给julia语言,需要采用julia函数unsafe_wrap对julia函数赋值。如对于长度为len的c语言数组carray,采用下列语句传递给julia

jarray = unsafe_wrap(Array{Int32},carray,len)

注意!unsafe_wrap函数c语言与julia语言共享数据内存,c或julia中对值进行修改,数组均发生变化

(5)结构体对应关系

julia语言与c语言结构体对应关系如下,定义julia语言结构体为:

mutable struct CArray
    len::Cint
    cArray::Ptr{Cdouble}
end

c语言结构体中元素应与julia语言保持一致,应定义为:

struct CArray{
    int len;
    double *cArray;
};
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值