have simple .jl (below are source files) program flow is: test.js calls c program which calls julia program
- when using svg extension
const result = generate_c(‘td’, 250, 250, ‘test_draw.svg’);
image is generated
- when using png extension get exception related to png library
const result = generate_c(‘td’, 250, 250, 'test_draw.png);
Segmentation fault
in expression starting at none:0
deflateReset at node (unknown line)
png_deflate_claim at /home/server/go/src/blockbook/ml/ca/server/recursiveDynamic/dist/share/julia/artifacts/79994d5aa1ffc0e9e42f2348a7f9c584dbe20204/lib/libpng16.so (unknown line)
this error is related to calling build so library from node
followed project structure PackageCompiler.jl for libs (al works just fine if one is calling it from a c program but not as shared (so) library
see also make file (below)
test_draw.jl
using CairoMakie
CairoMakie.activate!()
export generate_test_draw
function generate_test_draw(width::Integer, height::Integer, output_path::String)
fig = Figure(size = (width, height))
ax = Axis(fig[1, 1]; title = “Simple Square”)
# Define square corners manually
points = [Point2f(0.25, 0.25), Point2f(0.75, 0.25),
Point2f(0.75, 0.75), Point2f(0.25, 0.75)]
poly!(ax, points, color = :blue)
save(output_path, fig)
end
rdlib.js
export generate
using Base: Cint, Cstring, unsafe_string
include(“cantor_set.jl”)
include(“hilbert_curve.jl”)
include(“test_draw.jl”)
C-callable function via @ccallable
Base.@ccallable function generate(ctype::Cstring, width::Cint, height::Cint, o::Cstring)::Cint
ctype_str = unsafe_string(ctype)
output_str = unsafe_string(o)
if ctype_str == "td"
generate_test_draw(width, height, output_str)
else
@warn "Unknown ctype: $ctype_str"
return 1 # Non-zero to indicate error
end
return 0
end
c program
generate.c
#include <stdio.h>
#include “julia_init.h”
#include “rdlib.h”
int generate_c(const char *ctype, int width, int height, const char *output_path)
{
init_julia(0, NULL); // Initialize Julia runtime; adjust if you need argc/argv
int status = 0;
status = generate(ctype, width, height, output_path);
if (status != 0) {
fprintf(stderr, "generate_%s failed with status %d\n", ctype, status);
}
shutdown_julia(0); // Shutdown Julia runtime
return status;
}
test.js
const koffi = require(‘koffi’);
// Load the shared library
const lib = koffi.load(‘./dist/lib/librdlib_c.so’);
// Define the C-callable function signature
const generate_c = lib.func(‘int generate_c(const char*, int, int, const char*)’);
// Call the function
const result = generate_c(‘td’, 250, 250, ‘test_draw.svg’);
console.log(‘generate() returned:’, result);
– Make file
.DEFAULT_GOAL := all
JULIA ?= julia
DLEXT := (shell (JULIA) --startup-file=no -e ‘using Libdl; print(Libdl.dlext)’)
TARGET=“dist”
RDLIB_INCLUDES = (TARGET)/include/julia_init.h (TARGET)/include/rdlib.h
RDLIB_PATH := (TARGET)/lib/librdlib.(DLEXT)
build-library: build/build.jl src/rdlib.jl
(JULIA) --startup-file=no --project=. -e 'using Pkg; Pkg.instantiate()'
(JULIA) --startup-file=no --project=build -e ‘using Pkg; Pkg.instantiate(); include(“build/build.jl”)’
INCLUDE_DIR = $(TARGET)/include
build-c-library:
gcc -shared -fPIC generate.c -o (TARGET)/lib/librdlib_c.so \
-I(INCLUDE_DIR) -L$(TARGET)/lib -ljulia -lrdlib
build-executable:
gcc generate.c -o generate -I$(INCLUDE_DIR) -L$(TARGET)/lib -ljulia -lrdlib
all: build-library build-c-library build-executable
clean:
(RM) *~ *.o *.(DLEXT)
(RM) -Rf (TARGET)
.PHONY: build-library build-executable clean all