Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple C# DLL import fails #139

Closed
geoff2273 opened this issue Oct 23, 2018 · 6 comments
Closed

Simple C# DLL import fails #139

geoff2273 opened this issue Oct 23, 2018 · 6 comments

Comments

@geoff2273
Copy link

geoff2273 commented Oct 23, 2018

First off, let me say how great this tool is. I've been able to generate exes with Julia 1.0, which is very pleasing. This is on Windows 10 x64.

However, I'm now struggling to import a DLL generated using this tool into a simple C# program because it raises an access violation:

Test!


Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x0 --
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at JuliaDllCall.Program.julia_main(String[] args)
   at JuliaDllCall.Program.Main(String[] args) in C:\.....\JuliaDllCall\JuliaDllCall\Program.cs:line 17
Press any key to continue . . .

Here is the culprit code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace JuliaDllCall
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Console.WriteLine("Test!\n");
            julia_main(new string[] { "" });
        }

        [DllImport(@"C:\...\Julia\builddir\hello.dll")]
        public static extern int julia_main(String[] args);
    }
}

hello.dll has been compiled running build_shared_lib("hello.jl") and is the example hello.jl distributed with PackageCompiler.

I've set Visual Studio to target x64, I already dealt with an earlier error which was due to targetting x86.

@geoff2273
Copy link
Author

Ok I think I understand where I am going wrong with this. Is it the case that I need to also link against libjulia.dll too? I can't find any example of how to do this for Julia with C#, if that is indeed possible.

I can find examples of how to embed Julia in a C application. I also see how PackageCompiler builds the exe by linking the DLL to program.c. However, my C is sufficiently poor that I don't understand how to write a DLL that enables me to call a Julia function multiple times without the overhead of jl_init every time. I will attempt to at least produce a DLL that loads jl_init every time as a stepping stone...

Any help greatly appreciated.

@geoff2273
Copy link
Author

geoff2273 commented Oct 23, 2018

My final thoughts for the day, and until someone who knows what they are doing is able to point me in the right direction: I have taken the hello.dll built from hello.jl, and made a new shared library using program.c (and exporting main). I now import this new dll into C# and try to call main but I get a new error!

I simply changed line 19 of program.c to __declspec(dllexport) int main() and assigned argc to 1 and argv to "test".

I compiled the new dll using gcc '-DJULIAC_PROGRAM_LIBNAME="hello_dll.dll"' -shared -o hello_dll.dll program_dll.c hello.dll -std=gnu99 '-IC:\...\Julia-1.0.0\include\julia' -DJULIA_ENABLE_THREADING=1 '-LC:\...\Julia-1.0.0\bin' -Wl,--stack,8388608 -ljulia -lopenlibm -m64

The error I get is ERROR: System image file failed consistency check: maybe opened the wrong version? Press any key to continue . . .

I feel like I am so close to being able to use Julia but I'm just not quite able to get this to work.

EDIT: I only have one version of Julia on my PC.

EDIT: Forgot to give my C# code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace JuliaDllCall
{
    class Program
    {
        static void Main(string[] args)
        {

            System.Console.WriteLine("main\n");
            main();
            System.Console.WriteLine("DONE!\n");

        }

        [DllImport(@"C:\...\Julia\builddir\hello_dll.dll")]
        public static extern int main();
    }
}

@geoff2273
Copy link
Author

Solved!

Everything started working when I kept JULIAC_PROGRAM_LIBNAME consistent in my compile options:
'-DJULIAC_PROGRAM_LIBNAME="hello.dll"'

I have no idea what the point of JULIAC_PROGRAM_LIBNAME is supposed to do, but if it changes it seems to give the image consistency check error.

@netlander
Copy link

Having the same problem:

Can you summarise what you have actually done?

Was using program.c really necessary?

Where do you set -DJULIAC_PROGRAM_LIBNAME="hello.dll" flag?

Thanks

@mroavi
Copy link

mroavi commented Aug 3, 2019

You may want to take a look at this related issue which shows how to build a shared library with PackageCompiler.jl and call the resulting library from C++.

@KristofferC
Copy link
Member

https://github.com/simonbyrne/libcg has examples for C and Rust and it should not be too hard to adopt that to C#.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants