1

I have a DLL in pure C code. I would like to find a way to remove the library name prefix from the functions, classes, and structs; EX:

// lib.h
void foobar();
// lib.hpp
namespace foo {
    bar();
}

I would like to avoid simply writing a wrapper for every function, since I'd have to write it for every time I want to add a function. Is there a better / more efficient way of writing this?

I started writing the wrapper idea, but there's a lot of functions to write this for. Void pointers worked a little better, but still had the same issue.

Khrisys
  • 17
  • 1
  • 6
  • 2
    Please [edit] your question and add more details or background information. What exactly do you mean with "*every time I want to add a function*"? Adding a function or structure to the library and both the C and C++ interfaces? Adding another existing function/structure from the C interface to the subset in the C++ interface? Do you implement the library or can you modify its source code? – Bodo Nov 07 '22 at 15:27
  • "Is there a better / more efficient way of writing this?" For selected values of "better". Write an LLVM plugin, for example. Or any script that reads the list of the functions and writes source code for wrappers. There *is* some list somewhere, right? – n. m. could be an AI Nov 07 '22 at 16:55
  • What are you trying to accomplish with this name game? The code here means you would be able to write `foo::bar` instead of `foobar`. That seems pointless. And if you're planning on always writing `using namespace foo;` so you can skip the `foo::` prefix, just don't. – Pete Becker Nov 07 '22 at 17:04
  • @PeteBecker readability is in the eye of the beholder. – n. m. could be an AI Nov 07 '22 at 19:21

2 Answers2

2

Unless you are worried about name conflicts between existing C++ function names and the C library, how about just using extern "C" (in your C++ code) and call it (from your C or C++ code). For example:

extern "C" void f(int); // apply to a single function
extern "C" {    // or apply to a block of functions
    int g(double);
    double h(void);
};
void code(int i, double d)
{
    f(i);
    int ii = g(d);
    double dd = h();
    // ...
}

When code is enclosed within an extern “C” block, the C++ compiler ensures that the function names are un-mangled – that the compiler emits a binary file with their names unchanged, as a C compiler would do.
This approach is commonly used to accommodate inter language linkage between C++ and C.

from this Reference
more from cppprefference.com

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • How does this address OP's desire to write `foo::bar()` instead of `foobar()`? – hyde Nov 07 '22 at 18:09
  • @hyde - It does not. Your answer does a better job there, if that was really the need. (I guess I am assuming a little bit of a potential [X-Y](https://xyproblem.info/) problem here.), Reading the context of what OP is asking for emphasizes the desire more than anything else (IMO) the desire not to be forced to wrap every C function to be imported for use n a C++ program. The suggestion to use `extern "C"` addresses that. The OP `foobar` - `bar` idea seems orthogonal as it only propagates the very thing OP claims is to be avoided in the first place. (i.e. wrapping is required.) – ryyker Nov 07 '22 at 18:56
  • 1
    Not going to lie, I kind of forgot about extern "C" for a while. This was added to the library, and this answer was accepted. However, I am still going to implement @hyde 's answer, since that was exactly what I was looking for. – Khrisys Nov 08 '22 at 02:14
1

You could try this:

// lib.hpp
namespace foo {
    constexpr auto bar = foobar;
}

This should create a function pointer, and because it is constexpr, it should get resolved at compile time, so no performance hit. Also, constexpr is implicitly inline, so that (or static) can be omitted from this definition.

hyde
  • 60,639
  • 21
  • 115
  • 176
  • Does this address the main ask? (Which I think is: _"I would like to avoid simply writing a wrapper for every function"_) I am really not sure that ask can be satisfied though anyway. – ryyker Nov 07 '22 at 15:22
  • 1
    @ryyker There is no wrapper, just a function pointer. What do you expect, some kind of wildcard `namespace foo { * = foo*; }` or what? – hyde Nov 07 '22 at 15:25
  • LOL, No. The question was not intended as an indictment btw. It is just a question. And as I said in the other part of my comment, I am not sure the primary ask of OP is possible. Your suggestion, as far as I can tell does not address this. i.e. it would have to be applied _1-each_ for every C library function that is to be brought into use in the C++ program. – ryyker Nov 07 '22 at 15:29
  • This was simpler than my current solution (```namespace foo { void bar() { foobar(); ]} ```), so I will implement this answer. @rykker was also correct however. So both will be added as design choices into the library. – Khrisys Nov 08 '22 at 02:16
  • @Khrisys Ah, I assumed you had working code, because you didn't say you were unable to call `foobar()` from C++ at all. You may find these useful: https://stackoverflow.com/q/3789340/1717300 and https://stackoverflow.com/q/16850992/1717300. Anyway, just since you commented, it's customary to upvote useful answers here, in addition to accepting the answer you like best. – hyde Nov 08 '22 at 05:32
  • @Khrisys Also note that if you so choose, you can hide the `foobar()` from C++ global namespace if you so choose. It will not be as pretty, and (in the easy case) the C library will still have its global symbols exposed, they'll just not be defined in the C++ code. – hyde Nov 08 '22 at 05:38