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

Export jl_get_function #22190

Closed
wants to merge 1 commit into from
Closed

Conversation

ihnorton
Copy link
Member

@ihnorton ihnorton commented Jun 2, 2017

We use this as an example in the docs, so it should actually be usable.
I don't know why it was initially declared STATIC_INLINE, but it does
enough work that inlining seems pointless.

ref:

https://stackoverflow.com/questions/44314254/embedding-julia-script-into-c-jl-get-function-doesnt-exist

@ihnorton ihnorton added the embedding Embedding Julia using the C API label Jun 2, 2017
@ihnorton ihnorton added this to the 0.6.0 milestone Jun 2, 2017
We have this as an example in the docs, so it should actually be usable.
I don't know why it was initially declared STATIC_INLINE, but it does
enough work that inlining seems pointless.

ref:

https://stackoverflow.com/questions/44314254/embedding-julia-script-into-c-jl-get-function-doesnt-exist
@ihnorton ihnorton force-pushed the export_jlgetfunc branch from 58698a5 to 5f0e564 Compare June 2, 2017 14:28
@yuyichao
Copy link
Contributor

yuyichao commented Jun 2, 2017

Being in the header should be enough.

@ihnorton
Copy link
Member Author

ihnorton commented Jun 2, 2017

Being in the header should be enough.

Mind to expand on that?

  • it was not previously exported
  • putting JL_DLLEXPORT STATIC_INLINE is a no-op
  • JL_DLLEXPORT alone with function body in the header violates ODR

Copy link
Contributor

@yuyichao yuyichao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm saying is that we shouldn't do this.

  1. It being not exported doesn't matter. A static inline function in the header is a public API.
  2. We don't guarantee and will never be able to guarantee that all public C API are exported functions
  3. This function is a simple helper for C code which is why it's a static inline function. It isn't as useful for scripting. The right fix here is to document what this function do and what scripting language binding can do.

@yuyichao yuyichao removed this from the 0.6.0 milestone Jun 2, 2017
@ihnorton
Copy link
Member Author

ihnorton commented Jun 2, 2017

Ok. Ideally there would be a documented difference between the "julia.h public C API" and the "(non-include) embeddable C API with export guarantees" (look at Python or Lua for example). Probably 50% of the embedding questions we get are about using Julia from non-C languages, and I don't think it is unreasonable for people to try to translate the manual examples without deeply understanding the whole julia.h (and all the #define and sub-files; STATIC_INLINE is defined 3 includes deep). But that will have to be done some other time.

@ihnorton ihnorton closed this Jun 2, 2017
@yuyichao
Copy link
Contributor

yuyichao commented Jun 2, 2017

FWIW, small functions like this would be the last thing they need to worry about in terms of function/macro. The GC push and pop macros cannot be functions and the code in that stackoverflow questions is missing at least 3 roots.

@ihnorton ihnorton deleted the export_jlgetfunc branch June 2, 2017 18:21
@ihnorton
Copy link
Member Author

ihnorton commented Jun 2, 2017

If Julia only supports embedding in C and C++, then that seems like a fairly important thing to document...

@yuyichao
Copy link
Contributor

yuyichao commented Jun 2, 2017

If Julia only supports embedding in C and C++

No that's not at all the case, since pyjulia exists. The embedding doc, and more importantly the examples in the embedding doc, is obviously in C/C++. What other language to do strongly depends on the language ffi and the limitation of those ffi implementation should be familiar to anyone who want to write language bindings. As an example, I believe python's cffi would have no issue at all calling the inlined jl_get_function function or any of the simple function-like macros.

@ihnorton
Copy link
Member Author

ihnorton commented Jun 7, 2017

Ok, fair enough. For

The GC push and pop macros cannot be functions

pyjulia uses the "global root array" implemented in PyCall for every object conversion. A similar, generic preserve/unpreserve could be provided in the C API to make non-C embedding use simpler. (this is what people seemed to want from the old jl_gc_preserve...)

I believe python's cffi would have no issue at all calling the inlined jl_get_function function or any of the simple function-like macros.

In a CPython extension? Sure ...
For "CFFI" both PyPy and CPython (libffi) versions use dlopen/dlsym just like everyone else. I'm not sure how they are going to call a non-exported function either.

@yuyichao
Copy link
Contributor

yuyichao commented Jun 7, 2017

(this is what people seemed to want from the old jl_gc_preserve...)

I agree. It was removed because it never does that.... I think it'll be useful to have a simulated ref counting API. Though I'll probably not work on it unless there's more general interest....

And I'm using cffi just as an example of a (C) "API" level ffi. The cffi module in python support API level binding by parsing the header and calling external compilers so it can support all C APIs. After compiling the C code it'll obvious use dlopen for "linking". It's similar to how Cxx.jl works.

@BambOoxX
Copy link

Hello, sorry to fall back very late on this, but I started working on binding the libjulia.dll into a C# program, and I was counting on using jl_get_function at least as an intermediate step. Finding that it is not exported is quite a bummer, when trying to reproduce the examples in the documentation... I am currently tring to reproduce its behavior from jl_get_global with little success so far ...

@vtjnash
Copy link
Member

vtjnash commented Apr 23, 2021

It is simply jl_get_global(m, jl_symbol(name)), which should be readily available to you?

@BambOoxX
Copy link

@vtjnash the problem is I have to handle a jl_sym_t type in C# when using jl_symbol. I could not declare this type correctly in C# so far... With jl_get_function you don't have to use this type.

@vtjnash
Copy link
Member

vtjnash commented Apr 23, 2021

All objects should typically be handled as void* (aka jl_value_t*) by user libraries, including this one.

@BambOoxX
Copy link

BambOoxX commented Apr 24, 2021

All objects should typically be handled as void* (aka jl_value_t*) by user libraries, including this one.

@vtjnash Well, this works in C/C++, but how would you adapt this to C# ? With jl_symbol and jl_get_global defined in C# as

[DllImport(<libjulia_path>), CallingConvention = CallingConvention.Cdecl] public static extern IntPtr jl_symbol(string fun_str)
[DllImport(<libjulia_path>), CallingConvention = CallingConvention.Cdecl] public static extern IntPtr jl_get_global(IntPtr mod,IntPtr fun_symbol)

I get Memory Access violation errors, while I only use pointers to handle data...

@GeorgeS2019
Copy link

@GeorgeS2019 GeorgeS2019 mentioned this pull request Oct 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
embedding Embedding Julia using the C API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants