undefined reference to 'SetCurrentConsoleFontEx'? - c

When compiling this code:
PCONSOLE_FONT_INFOEX Font_Info;
//Adjust heights
Font_Info.dwFontSize.X = 9;
Font_Info.dwFontSize.Y = 9;
SetCurrentConsoleFontEx( StdHandle, FALSE, Font_Info);
GCC reports
undefined reference to 'SetCurrentConsoleFontEx'
But MSDN says that the header is #include<windows.h>
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686200(v=vs.85).aspx
Why? And how to resolve this problem ? THANKS.
PS,
I couldn't find any declaration in wincon.h and windows.h

This would not be the first time a function is missing from MinGW's SDK, and especially not a recent function like SetCurrentConsoleFontEx which is only exposed from Vista onwards.
Your libkernel32.a is too old for it; if you want to use this function from MinGW, you may need to access it dynamically instead.

Undefiend reference refers to a linkage problem. Definition may be in windows.h but you need to link to the appropriate library (Kernel32.lib) to generate final binary.

Related

override/redefine a C-Function which has a section attribute

I have the case where I need to overwrite some C-Functions of an SDK we use. The SDK is compiled as a lib and the functions we need to override are marked with
__attribute__((weak))
This works as it should when linking.
We override those functions then later in our files with the wanted definition.
Background:
The reason is that the SDK is not working in a standalone way but always needs a special tool which generates some global objects which are needed in the init-functions of the SDK. And we wanted to get rid of the tool and thus need new init-functions which do not rely on the global objects but on passing the configuration via pointer. Those functions are added additionally and no SDK-functions are removed.
Also the SDK shall not be altered in a way you can't use it anymore with the tool. So it must support both features, with the smallest changes possible which will not break the API and add support for the new API by us without the tool.
So following up, if we now have a function which has already an attribute defined, which references to a section like
void __attribute__((section(".text.random"))) Random_init(){}
it is not possible to override Random_init.
I do not get errors like it was redefined or anything but undefined symbols while linking which refer to those global objects, which of course are not generated anymore and are only used by the function which shall be overriden. And this works for all other 20 init-functions only for this one it does not and the only difference is the attribute already there.
I tried adding it together:
void __attribute__((weak, section(".text.random"))) Random_init()
which also does not work.
I also tried to add the attribute to the redefinition, but this also does not help.
We cannot just erase the section-attribute since it needs to be there for all the entities using the tool.
The compiler we use is a clang based TI LTS1.3.1-compiler.
I would like to provide a minimal example but since this combination only works with the sdk-code beeing compiled to a lib first, I just cannot.
I just try to show it:
SDK-function which is compiled inside the lib, c-file "Random.c":
extern RandConfig gRandConfig[];
extern int32_t gRandConfigNum;
void __attribute__((weak, section(".text.random"))) Random_init()
{
uint32_t i;
for (i = 0; i < gRandConfigNum; i++)
{
Random_setSpecial(i,
(void*)gRandConfig[i].baseAddr,
gRandConfig[i].size,
&gRandConfig[i].attrs
);
}
}
related Header-file, Random.h:
void Random_init();
The gRandConfig and gRandSpecialConfig are produced in code by the tool, which are then linked against the library and we don't want to use them anymore.
All the context where this shall happen is in C but the libs are used from C++-context.
So for example this is how the override would look like in our .cpp-files:
#include "Random.h"
extern "C"
{
void Random_init()
{
}
}
The result when linking:
undefined first referenced
symbol in file
--------- ----------------
gRandConfig ../../../../sdk-build/sdk.lib<Random.obj>
gRandConfigNum ../../../../sdk-build/sdk.lib<Random.obj>
The included header by the sdk also has guards for __cplusplus. So it shouldn't be a language issue.
Also we issued the compiler to compile with -ffunction-sections which shall at least help to sort unneeded functions out later on. But anyway it does not. Even when the function gets never called by anyone.
A dirty solution would be to just add dummy-variables for this one, so it's satisfied and does not complain but as you can imagine, that would be a workaround which produces a lot of problems later on and also takes space where we need every Byte of space.
Could it be that an section-function-attribute prevents the function from being overriden? I did not find anything at the gnu-documantation which says that one cannot override a function with an attribute.

Why does this work? Being able to use a function from standard libraries by declaring the prototype without including the headers

I've been playing around my code editor and accidentally made this. This compiles fine, and works as intended. For additional context, I'm using GCC on Debian 11. As for how I knew the prototypes, VS Code's IntelliSense told me.
Why does it work, and how? Neither <stdio.h> nor <math.h> is included.
double pow(double _x, double _y);
int printf(const char *__restrict__ __format, ...);
int main(void)
{
printf("%f\n", pow(2, -1));
}
Output: 0.500000
You can declare your functions like you did or by including the relevant header file(s) (preferred). gcc will link in the definitions found in libc unless you tell it not to (with -nolibc)
It works because the C standard explicitly requires it to work.
7.1.4 Provided that a library function can be declared without reference to any type defined in a header, it is also permissible to declare the function and use it without including its associated header.
The standard library is linked into most C projects. If you created a standard project, your IDE most likely took care of that part for you in the background.
Depending on how the compiler is configured, it may drag the functions in from the libc if they are defined as well. This allows a bit of optimization.
The header files tell your program how to access those functions. If the library is linked, then all of its functions are there, whether the header file is or not. You didn't magically bypass anything or anything like that. You just provided an alternative declaration of the function.

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.

Why redefinition of a function which is already present in dynamic or static library does not throw any error?

Wy redefinition of function already present in dynamic library does not throws any compilation and linking error?
In the below function
#include "calc_mean.h"
#include <stdio.h>
int mean(int t, int v) {
return 0;
}
int main () {
int theMean = mean(3,6);
printf("\n %d\n",theMean);
}
Inside the shared library Definition of mean function already present as below.
#include <stdio.h>
#include "calc_mean.h"
int mean(int a, int b) {
return (a+b)/2;
}
The definition of mean function is already present in the shared library libmean.so. But during compilation I don't see any redefinition error and compilation is successful.
And on successful execution the o/p I see is 0 instead of 4 so the function definition of mean inside the shared library is not getting executed but the one inside the main module is getting executed.
Why is this happening so?
The linker only links in a function from a library if the function had not yet been found during the compilation/linking process.
The reason for the difference in functionality is that there are different types of symbols. A library function is a weak symbol. It is only included if it is not already defined. nm is a tool for listing the symbols in an object or executable. In its man-page you can find a list of the types of symbols.
There is also a wikipedia page on weak symbols.
Having two definitions of one externally-visible function (even if the definitions are identical, for non-inline functions) causes undefined behaviour, with no diagnostic required. (Ref: C99 6.9#5 and Annex J.2)
In C, some illegal code requires a compiler diagnostic and some doesn't. Typically the ones that do not require a diagnostic are because:
it would be considered too prohibitive to require all compilers to detect and report the error
there were existing systems in use that did not diagnose it and the Standard committee did not want to render an existing implementation non-conforming.
In this case, my guess would be that this is a case of the first one; they wanted to leave open the option for compilers/linkers to implement weak symbols as an extension, so they did not specify that the compiler must give a warning here. Or possibly it is actually difficult to detect this in general, I've never tried to write a linker!
It should be considered a quality-of-implementation issue if no diagnostic is given. Perhaps it is possible to pass different flags to your linker so that it does reject this code; if not then you could put a in bug report or a feature request.
Did you link correctly the shared library because the compiler should give the error :
multiple definition of 'mean'

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.

Resources