Function pointer usage with hierarchical control: xtern/namespace C++ - c

Below is a sample usage from an older and newer version of a software stack. How would the function usage and access differ with the hierarchical structuring of the two pieces of
code below:
namespace std
{
typedef void (*function)();
extern "C" function fn_ptr(function) throw();
}
And
extern "C++"
{
namespace std
{
typedef void (*function)();
function fn_ptr(function) throw();
}
}
The first one is easy but I wish to access fn_ptr from both C and
C++ based files in the 2nd example. Note that it is extern "C++" and there isn't much to find about extern "C++" usage on Stackoverflow or Google.

The second version does not allow direct access from a program written in C.
Of course, nothing stops the C program from calling some other C++ function declared extern "C", which in turn calls std::fn_ptr.
Although this point has been hammered into the ground in comments, it's worth noting that you are not allowed to define your own names in namespace std. Presumably the code you are quoting comes from a library implementation designed to be used in a stand-alone environment. Using namespace std is not relevant to the issue, and is just a distraction from your question.

Here is the unique approach to accessing a function defined in C++ from C. extern "C++" is implicit by default in standard.
Let us assume that you have a .c file (FileC.c) and you wish to call a function defined in .cpp (FileC++.cpp). Let us define the function in C++ file as:
void func_in_cpp(void)
{
// whatever you wanna do here doesn't matter what I am gonna say!
}
Do the following steps now (to be able to call the above function from
a .c file):
1) With you regular C++ compiler (or www.cpp.sh), write a very simple program that includes your function name (func_in_cpp). Compile your program. E.g.
$ g++ FileC++.cpp -o test.o
2) Find the mangled name of your function.
$ nm test.out | grep -i func_in_cpp
[ The result should be "_Z11func_in_cppv" ]
3) Go to your C program and do two things:
void _Z11func_in_cppv(void); // provide the external function definition at the top in your program. Function is extern by default in C.
int main(void)
{
_Z11func_in_cppv(); // call your function to access the function defined in .cpp file
}

Related

Is there a way in C to have the compiler/linker give an error if a function is not defined?

In my case I am writing a simple plugin system in C using dlfcn.h (linux). The plugins are compiled separately from the main program and result in a bunch of .so files.
There are certain functions that must be defined in the plugin in order for the the plugin to be called properly by the main program. Ideally I would like each plugin to have included in it a .h file or something that somehow states what functions a valid plugin must have, if these functions are not defined in the plugin I would like the plugin to fail compilation.
I don't think you can enforce that a function be defined at compile time. However, if you use gcc toolchain, you can use the --undefined flag when linking to enforce that a symbol be defined.
ld --undefined foo
will treat foo as though it is an undefined symbol that must be defined for the linker to succeed.
You cannot do that.
It's common practice, to only define two exported functions in a library opened by dlopen(), one to import functions in your plugin and one to export functions of your plugin.
A few lines of code are better than any explanation:
struct plugin_import {
void (*draw)(float);
void (*update)(float);
};
struct plugin_export {
int (*get_version)(void);
void (*set_version)(int);
};
extern void import(struct plugin_import *);
extern void export(struct plugin_export *);
int setup(void)
{
struct plugin_export out = {0};
struct plugin_import in;
/* give the plugin our function pointers */
in.draw = &draw, in.update = &update;
import(&in);
/* get our functions out of the plugin */
export(&out);
/* verify that all functions are defined */
if (out.get_version == NULL || out.set_version == NULL)
return 1;
return 0;
}
This is very similar to the system Quake 2 used. You can look at the source here.
With the only difference, Quake 2 only exported a single function, which im- and exports the functions defined by the dynamic library at once.
Well after doing some research and asking a few people that I know of on IRC I have found the following solution:
Since I am using gcc I am able to use a linker script.
linker.script:
ASSERT(DEFINED(funcA), "must define funcA" ) ;
ASSERT(DEFINED(funcB), "must define funcB" ) ;
If either of those functions are not defined, then a custom error message will be output when the program tries to link.
(more info on linker script syntax can be found here: http://www.math.utah.edu/docs/info/ld_3.html)
When compiling simply add the linker script file after the source file:
gcc -o test main.c linker.script
Another possibility:
Something that I didn't think of (seems a bit obvious now) that was brought to my attention is you can create small program that loads your plugin and checks to see that you have valid function pointers to all of the functions that you want your plugin to have. Then incorporate this into your build system, be it a makefile or a script or whatever. This has the benefit that you are no longer limited to using a particular compiler to make this work. As well as you can do some more sophisticated checks for other other things. The only downside being you have a little more work to do to get it set up.

How to alias C library functions?

I have a static C library that I can build with different compile time options (e.g. _BUILD_SMALL, _BUILD_FAST). It has a function
void Foo(void);
I would like to use a single instance of a benchmarking tool to benchmark the "small" and the "fast" versions of the library. I don't want to use .dlls.
How can I link to the "small" and the "fast" libraries and alias the function names so I can call the small version and the fast version. Ideally it would look something like:
void benchmark(void)
{
FAST_Foo();
SMALL_Foo();
}
More information:
The library can be built with different optimizations options -Os versus -O3. Also, the algorithms vary slightly (i.e. cached values vs looking up values always). I want to compare the size vs speed tradeoffs of the different versions. I'd like the unit tests and benchmarking to be ran on both versions of the library the easiest way possible.
This is just a variation of the method as given by #Michał Górny (I run out of comment space there)...
You could create an include file of the following form:
/* Automatically created file - do not edit or ugly dinosaur will eat you */
#ifndef PREFIX
# define RENAME(f)
#else
# define RENAME(f) PREFIX ## f
#endif
/* list all the function and variables you want to rename here in one place */
#define func_foo RENAME(func_foo)
#define func_bar RENAME(func_bar)
/* ... many more ... */
#undef RENAME
At least gcc allows you to specify the inclusion of a header file from command line with option -include rename.h (assuming this file is called rename.h). Because you use gcc lookalike options (-O3 and Os), I am assuming you use gcc in the rest of this answer. Otherwise, if your C compiler is reasonable, you should be able to do it in some similar way.
You can create easily two or even three versions of your library that can be linked in at the same time if you want, by providing different options for your C compiler (here through CFLAGS setting):
CFLAGS += -include rename.h -DPREFIX=fast_ -D_BUILD_FAST -O3 -DBENCHMARKING
CFLAGS += -include rename.h -DPREFIX=small_ -D_BUILD_SMALL -Os -DBENCHMARKING
CFLAGS += -D_BUILD_FAST -O2
If your library header files look very regular and if you declare the library private functions static, then it is easy to extract the functions from those header files by some dummy script using very simple regular expressions to automatically generate the rename.h file for you. This is a natural build target if you are using make or something similar. All the global variables also need to be renamed using the same method to allow simultaneous use.
There are three main points with this solution:
The ugly renaming business can be hidden in one file, you do not need to edit the actual source files - especially you do not need to clutter the source files but can keep them clean and easy to read.
The renaming can be easily automated, if you follow some simple principles (coding conventions followed for the header files and the header files will declare all the global variables and functions).
There is no reason to make benchmarking more cumbersome by needing to run your test program multiple times (this is relevant if you are as lazy as I am and dislike repetive tasks as violently as I do - I know many people do not care, it is somewhat a matter of preference).
One way would be: keep the same name for both and call appropriately depending on the compile time option set.
ifdef SMALL_FOO
void foo() {
/* Small foo code */
}
#endif
ifdef BIG_FOO
void foo() {
/* Big foo code */
}
#endif
Set the SMALL_FOO/BIG_FOO during compilation with -d.
As a quick solution, you can use macro to mangle the function name like:
#ifdef FAST
# define FUNC(x) FAST_##x
#else
# define FUNC(x) SLOW_##x
#endif
void FUNC(Foo)();
And now with -DFAST the library with FAST_Foo will be built; and without it, one with SLOW_Foo. Just note that you need to use the FUNC() macro in the implementation part as well (and whenever you are referring to that function from inside the library), and #ifdef FAST to switch between fast/slow code.
Just please don't use that in a production code.
If you attempt to link in both static libraries to the same executable, the second library listed in your link line will not have any effect, because all the symbols it provided was satisfied already by the first library. If you provided simple unique wrapper functions to call Foo, it would still fail, now because of multiple definitions. Here is an example:
/* x.c */
extern void Y_Bar ();
extern void Z_Bar ();
int main ()
{
Y_Bar();
Z_Bar();
}
This main calls unique wrapper functions, which are provided in liby.a and libz.a.
/* y.c in liby.a */
#include <stdio.h>
void Y_Bar () {
extern void Foo ();
Foo();
}
void Foo () {
printf("%s\n", "that Foo");
}
/* z.c in libz.a */
#include <stdio.h>
void Z_Bar () {
extern void Foo ();
Foo();
}
void Foo () {
puts("this foo");
}
Attempting to link the executable with -ly -lz will fail.
The easiest work around for you is to build two separate executables. Your benchmark driver could then execute both executables to compare their relative performance.
You say that you can build the library, changing the compile time options, so why not edit the code to change the names of the functions in each. (You'd be making two different versions of your library.)
Maybe you can use -D option when call gcc, like -D_FAST_, -D_SMALL_, or your can received a input parameter when using make, like use make CFG=FAST, make CFG=SMALL, in your makefile, you can define, when get parameterFAST, link to FAST library.

C: Pointer to inline function

I have a static inline function defined in an H file, and at one point in a C file, I'm assigning a pointer to the function, something like this:
foo.h:
static inline void frobnicate(void) {
// frobs something.
}
foo.c
#include "foo.h"
void execute(void (*func)(void) ) {
func();
}
void blahBlahBlah(void) {
execute(frobnicate);
}
bar.c
#include "foo.h"
// ...
frobnicate();
So I think what will happen here is that the compiler will inline the call to frobnicate from bar.c, but in foo.c, it will actually have to create a function to implement frobnicate, so that it can have a working pointer to it.
Can anyone confirm if my understanding is accurate, and correct me otherwise?
inline is one of the misnomers of the C standard. Its main meaning is to be able to put the definition of a function in a header file without having to deal with "multiple definition" problems at link time.
The official way in C99 and C11 to do what you want to achieve is to have the inline definition in the header file, without the static. Since you also need the symbol to be emitted you need to tell the compiler in which compilation unit this should be. Such an instantiation can be done by have a declaration in that .c file where you omit the inline keyword.
Most naturally you could use the .c file where you actually need the symbol.
Yes, you are right. When you take the pointer to the function the compiler must create an "stand alone" version where the code can be called as a normal function.
The benefit of inlining a function is that the calling code need not to be created and any other optimization can be aplied to integrate both the caller function and the inlined function. But when you need to do a regular call to the function(as when you take the address to call it latter), those optimizations are not possible anymore.

Linking LLVM JIT code to external C++ functions

I'm writing a LLVM scripting engine that JIT compiles scripting code in a custom language. My problem is that I'm unable to call external functions (even the C99 erf() function is failing).
For example if I extern "C" the erf function,
extern "C" double erft(double x){
return erf(x);
}
and create a function with external linkage
std::vector<const Type*> Double1(1,Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),Double1,false);
Function *erft = Function::Create(FT,Function::ExternalLinkage,"erft",TheModule);
get the following error message when running my script with erft(0.0) :
LLVM ERROR: Program used external function 'erft' which could not be resolved!
Doing the mapping manually,
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
will get me the following error:
declaration of `void llvm::ExecutionEngine::addGlobalMapping(const llvm::GlobalValue*, void*)' outside of class is not definition
Obviously I'm doing something very wrong. Any help would be much appreciated
Assuming you haven't disabled it (by calling EE->DisableSymbolSearching()) then LLVM will use dlsym() to find the symbols in the JIT program itself. Depending on your platform, that might mean that you need to build your JIT with -fPIC, or that it might not be available at all (such as on Windows).
Aside from automatic symbol searching, you can always register the individual functions yourself using EE->addGlobalMapping(GV, &function) where GV = the llvm::Function* function declaration that matches the native function you're calling. In your case with ertf() that's:
EE->addGlobalMapping(erft, &::erft);
Note that you named the global function erft() and the local variable erft, hence the "::". Please pick different names next time!
This might be happening because you forgot to add the "libm" depedency, try using:
[your module]->addLibrary("m");
See here for more information about the Module::addLibrary().
I don't know llvm, but this make no sense:
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
That defines a new function in C++. What you need to do is somehow register your function with LLVM. Defining that function is like trying to add new methods to the LLVM classes, not what you want to do.

In C, what does "public" mean when put before a global variable?

I'm going through the source code of the "less" unix tool by Mark Nudelman, and the beginning of main.c has many of the following:
public int logfile = -1;
public int force_logfile = FALSE;
public char * namelogfile = NULL;
etc. in the global scope, before the definition of main(),
What does public mean in this context? And more important, where can I find this information by myself? I searched using countless query combinations, and could not find this information, or any thorough C reference.
In the file less.h is your answer:
#define public /* PUBLIC FUNCTION */
It seems like public is only used as a marker for public/global functions and variables.
When compiled, it is expanded to nothing.
How to find this information?
Search the .c file from top to the location of the identifier you want more information about
If you do not find any declaration, look for #include directives
Open any included file and look for the declaration of what you are looking for
Repeat from step two for every included file
In this case, that was pretty simple.
This has nothing to do with C as such. If you look in the include file less.h you will see that the author has defined a number of preprocessor instructions. Some of them like 'public' is most likely for readability. E.g.:
/*
* Language details.
*/
#if HAVE_VOID
#define VOID_POINTER void *
#else
#define VOID_POINTER char *
#define void int
#endif
#if HAVE_CONST
#define constant const
#else
#define constant
#endif
#define public /* PUBLIC FUNCTION */
See how public is defined. It's translated to nothing and as you have already figured out it's in the global scope. However it's more readable and more obious that it's in the global scope. Also, one could argue that if the source is written consistently like this and a new version of C emerges that does have a public keyword, it's a matter of redefining the the header file and recompile to actually use it.
Preprocessing tricks like this can even be used in clever ways to have one source compile in different languages (like C++ and Java). This is not something you should be doing, but it's possible to it.
The options like HAVE_VOID you see in the example from less.h above are usually specified as compiler (actually preprocessor) options on compile time. So if you have a compiler and a version of C that supports the void keyword you would compile your source with:
g++ -g -DHAVE_VOID -Wall myprog.C -o
myprog
Everywhere the author uses VOID_POINTER in the source would then actually be considered by the compiler as:
void *
If you didn't specify HAVE_VOID the compiler would instead use
char *
which is a reasonable substitue.
TIP: Check your compiler's options to see if you have an option to just preprocess your sources. That way you can look at the actual source that gets sent to the compiler.
C doesn't have a keyword "public", so it's probably a macro defined in the less source code somewhere.
The definition of public as an empty pre-processor macro has been addressed in other answers. To find the definition, you probably want to use a tool like ctags/etags or cscope. (There are many tools to scan a source tree to generate this information.) For example, you can find the definition of public at line 55 of less.h by invoking:
$ ctags -dtw *.c *.h
$ vi -t public
Or, simply run ctags before you start editing anything. When you see a definition you don't understand, put the cursor on it and type ^] (that's control-right square bracket, and will work in vi-like editors.)

Resources