Thread overview
link to C++ function in a namespace whose name is a D keyword
Jan 06, 2016
Carl Sturtivant
Jan 06, 2016
Ali Çehreli
Jan 06, 2016
Alex Parrill
Jan 06, 2016
Jacob Carlborg
January 06, 2016
Hello,

From D I want to call e.g.

/* C++ prototype */
namespace ns {
    int try(int x);
}

without writing a C or C++ wrapper.

Presumably the following D doesn't work, because it doesn't mangle the name as if it's in the namespace ns.

pragma(mangle, "try") extern(C++, ns) int try_(int x);

So how to I get correct mangling here?

January 06, 2016
On 01/06/2016 10:35 AM, Carl Sturtivant wrote:
> Hello,
>
>  From D I want to call e.g.
>
> /* C++ prototype */
> namespace ns {
>      int try(int x);
> }
>
> without writing a C or C++ wrapper.
>
> Presumably the following D doesn't work, because it doesn't mangle the
> name as if it's in the namespace ns.
>
> pragma(mangle, "try") extern(C++, ns) int try_(int x);
>
> So how to I get correct mangling here?
>

This looks like an oversight to me. I tried the following workaround but it uses D mangling scheme:

import core.demangle;

// PROBLEM: No way of saying "mangle C++ name".
pragma(mangle, mangle!(int function(int))("ns::body"))
extern(C++, ns)
int body_(int x);

void main() {
    assert(ns.body_(42) == 42);
}

And yes, 'try' is a C++ keyword as well; so I moved to 'body. :)

Ali

January 06, 2016
On Wednesday, 6 January 2016 at 18:35:07 UTC, Carl Sturtivant wrote:
> Hello,
>
> From D I want to call e.g.
>
> /* C++ prototype */
> namespace ns {
>     int try(int x);
> }
>
> without writing a C or C++ wrapper.
>
> Presumably the following D doesn't work, because it doesn't mangle the name as if it's in the namespace ns.
>
> pragma(mangle, "try") extern(C++, ns) int try_(int x);
>
> So how to I get correct mangling here?

Isn't try a C++ keyword though? Wouldn't that make it impossible to use in an identifier?
January 06, 2016
On 2016-01-06 19:35, Carl Sturtivant wrote:
> Hello,
>
>  From D I want to call e.g.
>
> /* C++ prototype */
> namespace ns {
>      int try(int x);
> }
>
> without writing a C or C++ wrapper.
>
> Presumably the following D doesn't work, because it doesn't mangle the
> name as if it's in the namespace ns.
>
> pragma(mangle, "try") extern(C++, ns) int try_(int x);
>
> So how to I get correct mangling here?
>

A really ugly workaround is:

1. Declare a extern(C++) function in the "ns" namespace with the same length as the name you want, "foo" for example

extern (C++, ns)
{
    int foo(int x);
}

2. Print the mangling of the function

pragma(msg, foo.mangleof); // __ZN2ns3fooEi on OS X

3. Replace "foo" with the name you actually want, "try" in this case

__ZN2ns3fooEi -> __ZN2ns3tryEi

4. Use pragma(mangle) to set the mangled name

pragma(mangle, "__ZN2ns3tryEi") extern (C++) int try_(int x);

-- 
/Jacob Carlborg