(я редактирую свой первоначальный пост, чтобы добавить дополнительную информацию)
Я недавно переехал в Джулию из-за ее прекрасной способности создавать двоичные файлы из кода.
Хотя я После этой документации Мне удалось создать двоичный файл.
Теперь я собираюсь передать массив в этот двоичный файл. Как упомянуто в документации, аргументы можно передавать с помощью глобальной переменной ARGS.
Я не уверен, как это может помочь в получении / возврате массива.
Чтобы быть более точным c, я хотел бы:
- написать мой алгоритм в Julia (который получает массив, выполняет некоторые вычисления и возвращает новый массив)
- выполните прекомпиляцию
- создайте sysimage
- создайте общую библиотеку
и затем вызовите ее так же, как в документации
РЕДАКТИРОВАТЬ: Хотя вышеприведенное выглядело довольно сложно, я подумал, что мог бы последовать примеру здесь , но просто создать свой собственный модуль. Это не сработало.
Вот что я попробовал:
Я создал "my_test.jl"
module my_test
export real_main
export julia_main
function real_main(x::Float64, y::Float64)
println("from main " , x, " " , y)
end
Base.@ccallable function julia_main(x::Float64, y::Float64)::Cint
try
real_main(x,y)
return 0
catch
Base.invokelatest(Base.display_error, Base.catch_stack())
return 1
end
return 0
end
if abspath(PROGRAM_FILE) == @__FILE__
julia_main(3.,4.)
end
end
, а затем предварительно скомпилировал его, используя:
julia --startup-file=no --trace-compile=app_precompile.jl my_test.jl
Как только прекомпиляция прошла успешно, я создал create_sysimage.jl:
Base.init_depot_path()
Base.init_load_path()
@eval Module() begin
Base.include(@__MODULE__, "my_test.jl")
for (pkgid, mod) in Base.loaded_modules
if !(pkgid.name in ("Main", "Core", "Base"))
eval(@__MODULE__, :(const $(Symbol(mod)) = $mod))
end
end
for statement in readlines("app_precompile.jl")
try
Base.include_string(@__MODULE__, statement)
catch
# See julia issue #28808
Core.println("failed to compile statement: ", statement)
end
end
end # module
empty!(LOAD_PATH)
empty!(DEPOT_PATH)
Затем я построил общую библиотеку на основе этого образа в 2 этапа:
julia --startup-file=no -J"$JULIA_DIR/lib/julia/sys.so" --output-o sys.o create_sysimage.jl
gcc -g -shared -o libsys.so -Wl,--whole-archive sys.o -Wl,--no-whole-archive -L"$JULIA_DIR/lib" -ljulia
Как только это удастся, я создал файл cpp для использования библиотеки выше. Поэтому my_test. cpp:
#include <julia.h>
JULIA_DEFINE_FAST_TLS()
int main()
{
libsupport_init();
jl_options.use_compiled_modules = JL_OPTIONS_USE_COMPILED_MODULES_YES;
jl_options.image_file = JULIAC_PROGRAM_LIBNAME;
jl_options.image_file_specified = 1;
jl_init_with_image(NULL,JULIAC_PROGRAM_LIBNAME);
//Enabling the below gives a better explanation of te failure
/*
jl_eval_string("using Main.my_test.jl");
if (jl_exception_occurred()) {
jl_call2(jl_get_function(jl_base_module, "showerror"),
jl_stderr_obj(),
jl_exception_occurred());
jl_printf(jl_stderr_stream(), "\n");
jl_atexit_hook(2);
exit(2);
}
jl_module_t* LA = (jl_module_t *)jl_eval_string("Main.my_test");
if (jl_exception_occurred()) {
jl_call2(jl_get_function(jl_base_module, "showerror"),
jl_stderr_obj(),
jl_exception_occurred());
jl_printf(jl_stderr_stream(), "\n");
jl_atexit_hook(3);
exit(3);
}
*/
jl_function_t *func1 = jl_get_function(jl_main_module, "julia_main");
if (jl_exception_occurred()) {
jl_call2(jl_get_function(jl_base_module, "showerror"),
jl_stderr_obj(),
jl_exception_occurred());
jl_printf(jl_stderr_stream(), "\n");
jl_atexit_hook(4);
exit(4);
}
jl_value_t* in1 = jl_box_float64(12.);
jl_value_t* in2 = jl_box_float64(24.);
jl_value_t* ret = NULL;
JL_GC_PUSH3(&in1,&in2,&ret);
ret = jl_call2(func1, in1, in2);
JL_GC_POP();
jl_atexit_hook(0);
}
А затем скомпилируйте его следующим образом:
g++ -o pass_2_arrays_to_my_test_by_eval -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib -ljulia -L$CURRENT_FOLDER -lsys pass_2_arrays_to_my_test_by_eval.cpp $JULIA_DIR/lib/julia/libstdc++.so.6
JULIA_DIR
указывает на каталог установки Julia, а CURRENT_FOLDER
указывает на текущий рабочий каталог.
Сбой вызова pass_2_arrays_to_my_test_by_eval
с сообщением Segmentation Fault.
Насколько я понимаю, он не работает, потому что не может загрузить модуль (вы можете увидеть это, если откомментировать некоторые строки в cpp код).
Может ли кто-нибудь помочь с этим? Некоторые люди в прошлом, кажется, делают это без каких-либо проблем ( как здесь ).
Заранее большое спасибо!