Importing a system image dll with c#/c++/c

Greetings!
I am trying to embed Julia code using C# (or C/C++) and a generated Julia System Image (DLL, on Windows). The system image contains a few (selfmade) functions i am trying to call from C#. These are decorated with Base.@ccallable and inspecting the DLL file with DLL Export Viewer, they look like they are correctly exported.

  1. The System Image is created like this:
PackageCompiler.create_sysimage(:MyModule;
        sysimage_path = "path.../MyModule.dll",
        precompile_execution_file = "path.../Precompile_calls.jl")
  1. The module looks like this:
module MyModule
using CSV

Base.@ccallable function some_main()::Cint
    println("Julia Main called.")
    try
        real_main()
    catch
        Base.invokelatest(Base.display_error, Base.catch_stack())
        return 1
    end
    return 0
end

function real_main()
    println("Call function in same file.")
    func1()
    println("Call function in another file.")
    kniffel(3,5)
    return 0
end

Base.@ccallable function func1()::Cint
    println("Function1 called.")
    return 0
end

include("more.jl")

end # module
  1. Trying to import the DLL and calling the function(s) like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace CallSysimage
{
    class Program
    {

        [DllImport(@"path.../MyModule.dll")]
        public static extern int some_main();

        [DllImport(@"path.../MyModule.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern int func1();

        static void Main(string[] args)
        {
            try
            {
                some_main();
                func1();
            } 
            catch (Exception e)
            {
                Console.WriteLine("Error!");
                Console.WriteLine("StackTrace:\n" + e.StackTrace);
                Console.WriteLine("Message:\n" + e.Message);
            }

        }
    }
}

results in this exception:

Exception: EXCEPTION_ACCESS_VIOLATION at 0x0 -- Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at CallSysimage.Program.some_main()
   at CallSysimage.Program.some_main()
   at CallSysimage.Program.Main(System.String[])

How do i call the function from the system image correctly? I am pretty sure that the DLL and the function is “read correctly” since it gets past “DLL not found” and “Entry point not found” errors.
I am using Julia 1.4.2 and VisualStudio 2019 on Windows 10. I tried something similar with C and got a “Segmentation fault”.

I hope someone can help me here! Thank you!
joschv

https://docs.julialang.org/en/v1/manual/embedding/#High-Level-Embedding-1

and

https://github.com/JuliaLang/PackageCompiler.jl/blob/master/src/embedding_wrapper.c

might be useful. Note e.g. that you need to initialize the Julia runtime.

Thank you! I already made contact with these sources but was and am struggling and confirmation that i’m missing a lot (e.g Julia runtime initialization) helps.
“Update:” I am trying to follow Embedding Julia · The Julia Language and currently stuck with a #error: “No Target Architecture” when trying to build and run.

So just in case someone stumbles upon the same problems as me.
When following that example i got several errors like “PCONTEXT is undefined” “PLIST_HEADER is undefined”. I found a solve or workaround for the errors here.
Also i added #include <julia.h> in the main file since there was no “stdafx.h” created as far as i know. The file that actually compiles for me:

#define _AMD64_
#include <iostream>
#include <julia.h>

int main(int argc, char* argv[])
{
    /* required: setup the Julia context */
    jl_init();

    /* run Julia commands */
    jl_eval_string("print(sqrt(2.0))");

    /* strongly recommended: notify Julia that the
         program is about to terminate. this allows
         Julia time to cleanup pending write requests
         and run all finalizers
    */
    jl_atexit_hook(0);
    return 0;
}

1 Like