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.jl的create_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类型 |
---|---|---|---|
1 | int | Cint | Int32 |
2 | double | Cdouble | Float64 |
在声明 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;
};