Difficulty using ccall

I have a shared library file called /home/nxf93431/work/test/julia-gram-schmidt/libmean.so which contains a C function double mean(double a, double b) I try to run in Julia with ccall. I do the following:

using Libdl
push!(Libdl.DL_LOAD_PATH, “/home/nxf93431/work/test/julia-gram-schmidt/”)
ccall((:mean, “libmean”), Float64, (Float64, Float64), 2.0, 5.0)

but I get the following error:

ERROR: could not load library “libmean”
libmean.so: cannot open shared object file: No such file or directory

So I wonder if I do something wrong, and if so, I would like to know what it is.

What I’d do is

using Libdl
const libmean = dlopen("/home/nxf93431/work/test/julia-gram-schmidt/libmean.so")
@ccall libmean.mean(1.0::Cdouble, 5.0::Cdouble)::Float64

Be aware that hardcoding a path on your machine inside the code will make it very non-relocatable (trying to run it on a different machine would obviously fail), but it’s probably ok if this is for your local testing or local deploying.

1 Like

I tried your approach. It gives me a very long error message with

ERROR: ‘ccall’ requires the compiler

What was the very long error? Also what kind of system are you using. OS etc. versioninfo() would be cool too.

I can unfortunately not copy the message from the terminal I use. But it starts with

Internal error: encountered unexpected error during compilation of top-level scope:
TypeError(func=:ccall, context=“”, expected=Symbol, got=0x00000000003ce85a0))

At the end, it says

ERROR: ‘ccall’ requires the compiler

My OS is Linux (x86_64-linux-gnu). I use the version 1.8.1.

Educated guess: try to start Julia with

LD_LIBRARY_PATH="" julia

I tried starting Julia as you said. But I still get the same error when using @ccall.

I am a bit disappointed in the Julia documentation (https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/) on this topic. Not only is there not enough information to run a functional test case, but there is no mention of Libdl and of the macro @ccall as the function ccall is the only method presented there.

You will have to provide more information, including the C code, how you compile the library and the full error message, and how you installed julia.

The C code is very basic. Located in /home/nxf93431/work/test/julia-gram-schmidt/calc_mean.c, I have

double mean(double a, double b) {
  return (a+b) / 2;
}

The makefile I use is

CC=gcc 
 
CFLAGS=-c -Wall -fPIC
 
SOURCES=calc_mean.c 
OBJECTS=$(SOURCES:.c=.o)
 
.c.o:
	$(CC) $(CFLAGS) $< -o $@
 
lib: $(OBJECTS)
	$(CC) -shared -fPIC -o libmean.so $(OBJECTS)
 
clean:
	rm *.o *.so

The complete error message is

Internal error: encountered unexpected error during compilation of top-level scope:
TypeError(func=:ccall, context="", expected=Symbol, got=0x0000000000ef7eb0)
ijl_type_error_rt at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/rtutils.c:119
ijl_type_error at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/rtutils.c:127
interpret_symbol_arg at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/ccall.cpp:611
emit_ccall at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/ccall.cpp:1280
emit_expr at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:4751
emit_ssaval_assign at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:4315
emit_stmtpos at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:4562 [inlined]
emit_function at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:7416
jl_emit_code at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:7778
jl_emit_codeinst at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:7823
_jl_compile_codeinst at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jitlayers.cpp:119
jl_generate_fptr_impl at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jitlayers.cpp:332
jl_compile_method_internal at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2081 [inlined]
jl_compile_method_internal at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2025
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2359 [inlined]
ijl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2374
jl_toplevel_eval_flex at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/toplevel.c:897
jl_toplevel_eval_flex at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/toplevel.c:850
ijl_toplevel_eval_in at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/toplevel.c:965
eval at ./boot.jl:368 [inlined]
eval_user_input at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:151
repl_backend_loop at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:247
start_repl_backend at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:232
#run_repl#47 at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:369
run_repl at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:355
jfptr_run_repl_66557.clone_1 at /home/nxf93431/julia-1.8.1/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2367 [inlined]
ijl_apply_generic at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2549
#967 at ./client.jl:419
jfptr_YY.967_49700.clone_1 at /home/nxf93431/julia-1.8.1/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2367 [inlined]
ijl_apply_generic at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2549
jl_apply at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/julia.h:1838 [inlined]
jl_f__call_latest at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/builtins.c:774
#invokelatest#2 at ./essentials.jl:729 [inlined]
invokelatest at ./essentials.jl:726 [inlined]
run_main_repl at ./client.jl:404
exec_options at ./client.jl:318
_start at ./client.jl:522
jfptr__start_61720.clone_1 at /home/nxf93431/julia-1.8.1/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2367 [inlined]
ijl_apply_generic at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2549
jl_apply at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/julia.h:1838 [inlined]
true_main at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jlapi.c:575
jl_repl_entrypoint at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jlapi.c:719
main at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/cli/loader_exe.c:59
__libc_start_main at /lib64/libc.so.6 (unknown line)
unknown function (ip: 0x401098)
__libc_start_main at /lib64/libc.so.6 (unknown line)
unknown function (ip: 0x401098)
Internal error: encountered unexpected error during compilation of top-level scope:
TypeError(func=:ccall, context="", expected=Symbol, got=0x0000000000ef7eb0)
ijl_type_error_rt at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/rtutils.c:119
ijl_type_error at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/rtutils.c:127
interpret_symbol_arg at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/ccall.cpp:611
emit_ccall at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/ccall.cpp:1280
emit_expr at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:4751
emit_ssaval_assign at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:4315
emit_stmtpos at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:4562 [inlined]
emit_function at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:7416
jl_emit_code at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:7778
jl_emit_codeinst at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/codegen.cpp:7823
_jl_compile_codeinst at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jitlayers.cpp:119
jl_generate_fptr_for_unspecialized_impl at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jitlayers.cpp:380
jl_compile_method_internal at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2094 [inlined]
jl_compile_method_internal at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2025
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2359 [inlined]
ijl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2374
jl_toplevel_eval_flex at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/toplevel.c:897
jl_toplevel_eval_flex at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/toplevel.c:850
ijl_toplevel_eval_in at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/toplevel.c:965
eval at ./boot.jl:368 [inlined]
eval_user_input at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:151
repl_backend_loop at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:247
start_repl_backend at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:232
#run_repl#47 at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:369
run_repl at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/usr/share/julia/stdlib/v1.8/REPL/src/REPL.jl:355
jfptr_run_repl_66557.clone_1 at /home/nxf93431/julia-1.8.1/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2367 [inlined]
ijl_apply_generic at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2549
#967 at ./client.jl:419
jfptr_YY.967_49700.clone_1 at /home/nxf93431/julia-1.8.1/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2367 [inlined]
ijl_apply_generic at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2549
jl_apply at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/julia.h:1838 [inlined]
jl_f__call_latest at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/builtins.c:774
#invokelatest#2 at ./essentials.jl:729 [inlined]
invokelatest at ./essentials.jl:726 [inlined]
run_main_repl at ./client.jl:404
exec_options at ./client.jl:318
_start at ./client.jl:522
jfptr__start_61720.clone_1 at /home/nxf93431/julia-1.8.1/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2367 [inlined]
ijl_apply_generic at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2549
jl_apply at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/julia.h:1838 [inlined]
true_main at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jlapi.c:575
jl_repl_entrypoint at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jlapi.c:719
main at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/cli/loader_exe.c:59
__libc_start_main at /lib64/libc.so.6 (unknown line)
unknown function (ip: 0x401098)
ERROR: `ccall` requires the compiler

How did you install Julia? The only way I know to get the error you posted is when the julia process picks up an old libstdc++ from the system (and the error should be made much clearer by `load_library()` panics on errors when `err=0` by apaz-cli · Pull Request #47343 · JuliaLang/julia · GitHub). Can you please show exactly how you’re starting julia?

That has been already changed in the documentation of v1.9 (not yet released): Calling C and Fortran Code · The Julia Language.

2 Likes

Your C code and Makefile are fine. This is what I get with those files:

$ make
gcc  -c -Wall -fPIC calc_mean.c -o calc_mean.o
gcc  -shared -fPIC -o libmean.so calc_mean.o
$ julia 
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.8.0 (2022-08-17)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> ccall((:mean, "./libmean.so"), Cdouble, (Cdouble, Cdouble), 1.0, 2.0)
1.5

I agree that something seems to be strange with your Julia installation and/or runtime environment.

2 Likes

This works! I guess the solution is to give the exact path to the library within the ccall method, there is no need to use Libdl.