-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
exportc
mangles as C++ and doesn't work with importc
(C) with nim cpp
#10578
Comments
A proposal of mine would be a |
The "emit" trick actually works:
In C++ |
indeed; here's a better version of both approach that works with both const externCDecl = when defined(cpp): """extern "C" $1 $2 $3""" else: """$1 $2 $3"""
proc foobar1(a: int) {.exportc: "my_foobar1", codegenDecl: externCDecl.} = echo "ok1" # I added NIM_EXTERNC in the spec in https://github.com/nim-lang/Nim/pull/10022 so this should continue to work:
{.emit: "NIM_EXTERNC".}
proc foobar1(a: int) {.exportc: "my_foobar1".} = echo "ok1"
if the semantics are as follows then that'd be ok (that's basically rule 1 plus a special case of rule 2:
|
I'd mean something like this: |
I ended up on this issue today while trying to make Nim->C++ compiled .so work with a foreign language. I ended up doing: when defined(cpp):
{.push codegenDecl: """extern "C" $1 $2 $3""".}
proc hello() {.exportc.} =
echo "Hello from Nim!"
when defined(cpp):
{.pop.} @Araq Seems like this SO answer answers that:
|
Nim should allow controlling symbol mangling; it currently seems impossible with
nim cpp
.Using test example below:
test example
main.nim:
t0202b.nim:
very partial workaround
Here's my current workaround that works with
nim c
andnim cpp
It still doesn't let me mangle a c++ symbol the way I want, so it doesn't help if I need to export a symbol for a non-nim program that expects a given mangling over which I have no control.
workaround suggested by @Araq: I couldn't make it work
no success, please explain
workaround via emit: couldn't make it work
when you compile, it seems to work (no error!) but doesn't actually work:
the generated cpp code is:
[EDIT] (credits: @Araq)
this seems to work:
however, it breaks
nim c
compatibity; so, see proposal below.proposal
rule 1
when
exportc
is specified, it should implyextern "C"
so that it works seamlessly in tandem withimportc
; that's the most common use case and the one that'll lead to least bugs when we need to support bothnim c
andnim cpp
(either in isolation, or even when anim c
main links against anim cpp
shared library)Eg:
rule 2
We also allow (but as an opt-in option) for
exportc
to mangle as c++ as follows:note:
{.push: mangling: cpp.}
can be used for convenience to wrap lots of procs at oncepragma(mangle)
for this purpose;it allows flexibilty, for example by conrolling how a particular type
Foo
gets mangled (say, toFooAlias
), so that when a typeBar
that depends on it (egstd::vector<Foo>
) gets mangled (using c++ mangling rules), it'll use the nameFooAlias
inside the mangling ofBar
, as ifFoo
was namedFooAlias
in the 1st place.mangling
can support different options, eg:mangling:native
: use C or C++ mangling depending on whethernim c
ornim cpp
is usedmangling: cpp
: use C++ mangling withnim cpp
, and currently errorswith
nim c` but could add support in future (eg link or by calling c++ codegen for the declaration along with its minimal needed dependencies )mangling: objc
,mangling: d
(reserved for future use)The text was updated successfully, but these errors were encountered: