D2: importing a function from an external library with a different name was originally exported

I was translating a 3rd party library API written on CD. This library exports many named functions libname_foofunc

, libname_barfunc

etc., which is expected for a C library to prevent global namespace bloat. Since D is more modular than C, I want to provide more of D'ish's interface and get rid of the function prefix, so functions will look like libname.c.foofunc

and libname.c.barfunc

.

Since the library is unaware of my "enhancements", I need to somehow translate libname.c.foofunc

into libname_foofunc

and at the same time keep the correct external link, naming and invocation.

Assuming there is a way (which I don't know either) to tell the linker that the outer unresolved symbol __imp__D1c7foofuncFZi

matches _libname_foofunc

or libname_foofunc@0

(despite the fact that I have to do name manipulation with hands), there is still a problem saying D, which is called a convention.

In case I explicitly indicate extern(C) int foofunc()

in libname/c.di

, the problem with the call no longer occurs, but the name is translated to _foofunc

, which is also different from what is expected.

So, is there a way D to import someone else's function under a different name than it was exported?

I have about importing functions "as is" under their original names and then alias them for prefix counterparts, but that seems pretty clunky.

+3


source to share


4 answers


As far as reference is concerned, symbols are indeed C stuff, since we're talking about a C linker. D with bindings and exported symbols is basically the same as in C ++, so there are mangled names etc. You will have to create declarations for them in D using their original names, because that is what the linker expects. D does nothing else or magical to change this. There are only two ways you can use different names.

  • serves as your D-code. You can simply put aliases in any module where symbols are listed (since you must declare them in D anyway). Then your code can use either original names or aliases. I don't see anything wrong with that.

  • Create wrapper functions - either in C or D - and use your D code.



Aliases will definitely be better IMHO. They introduce no overhead and are less complex.

Regardless, the usual thing when you need to use the C libraries from D is to just use the C function names. You call C functions, and this fact should not be hidden. They are not D functions and do not act the same (even if they are similar), especially when it comes to who owns the memory of what you pass to the function. Strengthening their renaming is controversial. Usually when a D wrapper is written to give the API a cleaner, more D-like API (not just name changes) that C functions are no longer used directly. A good example of this in Phobos would be etc.c.curl vs std.net.curl. etcc.curl is a C API only and doesn't try to rename anything. It does not create any aliases to make the symbols conform to Phobos naming conventions or make them more D-like. This is, in fact,only D version of curl header files. On the other hand, std.net.curl builds on it to provide a more D-like API and abstraction. This is much more than renaming C functions.

+2


source


you can use

alias libname_foofunc foofunc;

      



this will keep the visibility libname_foofunc

but allow you to use foofunc

and it will be converted by the compiler tolibname_foofunc

+3


source


Considering the last paragraph FROM, the answer is NO. No other language can do it like you described, and it shouldn't. If API designers wanted to have function names the way you like, they would expose them that way ...

Now imagine group A of developers who prefer some_function()

, then group B who prefer someFunction()

, and group C who prefer someFunction()

...

Anti-aliasing is a must, whether you are using D or whatever. And so it should be. The API should be simple, straightforward and straightforward

+2


source


If you don't want to inject functions into modules, you can keep them inside structures and mimic some sort of namespace. For example. You can do it:

struct libname
{
    struct C
    {
        static int libname_foofunc();
        alias libname_foofunc foofunc;
    }

    static C c;
}

void main()
{
    libname.c.foofunc();
}

      

+1


source







All Articles