I have a library that provides a function func():
return_type func(type arg);
It was necessary to override it by my own implementation in my application. It was possible because the library provides a weak symbol func while the func symbol in my application is a strong one. (That is my understanding.)
Now I want to be able to call both implementations of func - library's implementatoin and my own implementation:
// The problem is that the names are the same.
func(); // Everything is OK, calling my implementation (in my application)
func(); // How can I call library's implementation now?
I can call my implementation because it overrides the implementation in the library. But how can I call the implementation in the library? How can I refer to it?
If the functions are in shared libraries, you can load them with dlopen and the obtain the symbols from dlsym. You can then have different function pointers for for the functions from each library.
If the functions are in a static library, you will need to modify the static library to change the name. This can be done with something like objcopy --prefix-symbols=foo_ foo.o. Not sure if this can be done directly on a .a in such a case, you might need to expand the archive.
Having added the prefix you will then need to modify any header files to take the new names either using a macro or something similar.
Related
I have a library libxx and inside that library there is a static function foo().
I want to write another function bar() which uses the function foo() as a subroutine.
Is there any way to do it without writing bar() on the file which the function foo() sits on and rebuilding the library?
Declaring a function static within a translation unit (object file / library) pretty much invalidates any assertions about that function's implementation. It could be completely inlined. It might use short-cuts with the calling conventions that would be incorrect when called externally.
On some OS/ABIs, the function will not be 'visible' in the sense that a .globl directive with ELF/Mach-O would provide, and the linker will prevent it, or the loader won't resolve it. In a shared library, it might not preserve position-independence outside its local use. The point is, you just can't do this safely or portably.
In short, you need to recompile the function as non-static, i.e., a global / visible symbol in the library, or have a static version available to your bar() function. Say, via static inline.
It sounds like you have the source code to libxx. If that's the case, and you'd like bar() to exist in the same library as foo() then you'll need to recompile libxx after adding bar() to it.
If your goal is to call libxx::foo() from another program/library then you can just link libxx to your other project (which has bar() in it). Once the library is linked to your main project all you need to do is call into the correct namespace and invoke foo(). Linking a library to your main project will require using a linker. Different development systems will have different ways of invoking the linker. For researching this further, I would advise that you search for "c++ linking to static library X" where X is your development system (ex: visual studio, xcode). I'm assuming this is a static library based on the tag you put on the question, but maybe you meant that foo() was a static method. It shouldn't matter if it's a static method or not, linking will work in the same way. If you are confused about what I mean when I write "static library" then maybe researching the difference between static and dynamically linked libraries will clarify.
Not within standard C/C++.
The function has an address which is callable or other functions which may allow the foo to be called indirectly.
But these are bad solutions
I have an application (A) which calls a third-party shared library (C). I want to write a library of my own (B) that intercepts calls from A to C, and in some cases replace the calls with my own code, in some cases do some extra processing, then call the matching function in C, and in some cases just forward the calls to C directly.
The application is open-source, so I could just change each call site to call a similarly-named function in B, then call the corresponding function in C when required, but that would be a lot of work and would make merging upstream changes in the application difficult. I do not have the source to the third-party library. If it was header-only then I could just use namespaces to achieve this but I'm not sure how to go about it when both my library and the third-party library seemingly need the exact same symbols defined.
Is there even any way to make this work? I'm primarily targeting OS X, but would like it to work on linux and then eventually Windows as well.
You can use LD_PRELOAD to point to your own shared library. With LD_PRELOAD all functions in your shared library will be called instead of functions with the same name in those other libraries.
If you wish to inject code and then call the original functions you will need to call dlsym to get the original function from the third party library.
There are some examples here: https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/
One solution is as follows.
In a header file, #define all functions you want to intercept to your wrapper functions.
#define foo wrap_foo
#define bar wrap_bar
Stick this in some header file that is included everywhere, so that all of the code includes this header. This header should get included before the header for the library that you are intercepting. gcc also has an -include option that causes a header file to be included in all sources.
The goal here is to replace all calls to actual functions with calls to the wrapper functions.
Now define your wrapper functions somewhere, and intercept the calls as you wish. This file should not include the wrapper header that you created earlier.
int wrap_foo() {
return foo();
}
int wrap_bar() {
return bar();
}
Link it all together.
Note that this will let you intercept calls to foo() and bar() etc. only in the code that is compiled including the wrapper header. Any pre-compiled code (in libraries or objects) will link to foo() and bar() etc. directly.
I have a dynamically linked linux executable that uses shared libraries. One of those libraries has a function that is used by other functions in that library - the object code of that function is contained in this library. I would like to provide alternative implementation of that function, so that instead of calling the original code that is in the library, those other functions would call my code.
Any way to do it?
Cannot do it without compiling the library with new changes.
If those functions are global or static functions, definitely you have to recompile.
If those functions are virtual member functions and if your application/library has hooks/expandability or factory kind of thing to new a derived object to the applications you can change it.
Otherwise you have to recompile the library code.
GCC has the ability to make a symbol link weakly via __attribute__((weak)). I want to use the a weak symbol in a static library that users can override in their application. A GCC style weak symbol would let me do that, but I don't know if it can be done with visual studio.
Does Visual Studio offer a similar feature?
You can do it, here is an example in C:
/*
* pWeakValue MUST be an extern const variable, which will be aliased to
* pDefaultWeakValue if no real user definition is present, thanks to the
* alternatename directive.
*/
extern const char * pWeakValue;
extern const char * pDefaultWeakValue = NULL;
#pragma comment(linker, "/alternatename:_pWeakValue=_pDefaultWeakValue")
MSVC++ has __declspec(selectany) which covers part of the functionality of weak symbols: it allows you to define multiple identical symbols with external linkage, directing the compiler to choose any one of several available. However, I don't think MSVC++ has anything that would cover the other part of weak symbol functionality: the possibility to provide "replaceable" definitions in a library.
This, BTW, makes one wonder how the support for standard replaceable ::operator new and ::operator delete functions works in MSVC++.
MSVC used to behave such that if a symbol is defined in a .obj file and a .lib it would use the one on the .obj file without warning. I recall that it would also handle the situation where the symbol is defined in multiple libs it would use the one in the library named first in the list.
I can't say I've tried this in a while, but I'd be surprised if they changed this behavior (especially that .obj defined symbols override symbols in .lib files).
The only way i know. Place each symbol in a separate library. User objects with overrides also must be combined to library. Then link all together to an application. User library must be specified as input file, your lib's must be transfered to linker using /DEFAULTLIB: option.
From here:
... if a needed symbol can be satisfied without consulting a library,
then the OBJ in the library will not be used. This lets you override a
symbol in a library by explicitly placing it an OBJ. You can also
override a symbol in a library to putting it in another library that
gets searched ahead of the one you want to override. But you can’t
override a symbol in an explicit OBJ, because those are part of the
initial conditions.
This behavior results from the algorithm adopted by the linker.
So for short, to override a function,
With GCC, you must use the __attribute__((weak)). You cannot rely on the input order of object files into the linker to decide which function implementation is used.
With VS toolchain, you can rely on the order of the object/lib files and you must place your implementation of the function before the LIB that implements the original function. And you can put your implementation as an OBJ or LIB.
There isn't an MS-VC equivalent to this attribute. See http://connect.microsoft.com/VisualStudio/feedback/details/505028/add-weak-function-references-for-visual-c-c. I'm going to suggest something horrible: reading the purpose of it here: http://www.kolpackov.net/pipermail/notes/2004-March/000006.html it is essentially to define functions that, if their symbols exist, are used, otherwise, are not, so...
Why not use pre-processor for this purpose, with the huge caveat of "if you need to do this at all"? (I'm not a fan of recommending pre-processor).
Example:
#ifdef USE_MY_FUNCTION
extern void function();
#endif
then call appropriately in the application logic, surrounded by #ifdef statements. If your static library is linked in, as part of the linking in process, tweak the defines to define USE_MY_FUNCTION.
Not quite a direct equivalent and very ugly but it's the best I can think of.
assume we were using gcc/g++ and a C API specified by a random committee. This specification defines the function
void foo(void);
Now, there are several implementations according to this specification. Let's pick two as a sample and call them nfoo and xfoo (provided by libnfoo and libxfoo as static and dynamic libraries respectively).
Now, we want to create a C++ framework for the foo-API. Thus, we specify an abstract class
class Foo
{
public:
virtual void foo(void) = 0;
};
and corresponding implementations
#include <nfoo.h>
#include "Foo.h"
class NFoo : public Foo
{
public:
virtual void foo(void)
{
::foo(); // calling foo from the nfoo C-API
}
};
as well as
#include <xfoo.h>
#include "Foo.h"
class XFoo : public Foo
{
public:
virtual void foo(void)
{
::foo(); // calling foo from the xfoo C-API
}
};
Now, we are facing a problem: How do we create (i.e. link) everything into one library?
I see that there will be a symbol clash with the foo function symbols of the C API implementations.
I already tried to split the C++ wrapper implementations into separate static libraries, but then I realized (again) that static libraries is just a collection of unlinked object files. So this will not work at all, unless there is a way to fully link the C libraries into the wrapper and remove/hide their symbols.
Suggestions are highly appreciated.
Update: Optimal solutions should support both implementations at the same time.
Note: The code is not meant to be functional. Perceive it as pseudo code.
Could you use dlopen/dlsym at runtime to resolve your foo call.
something like example code from link ( may not compile):
void *handle,*handle2;
void (*fnfoo)() = null;
void (*fxfoo)() = null;
/* open the needed object */
handle = dlopen("/usr/home/me/libnfoo.so", RTLD_LOCAL | RTLD_LAZY);
handle2 = dlopen("/usr/home/me/libxfoo.so", RTLD_LOCAL | RTLD_LAZY);
fnfoo = dlsym(handle, "foo");
fxfoo = dlsym(handle, "foo");
/* invoke function */
(*fnfoo)();
(*fxfoo)();
// don't forget dlclose()'s
otherwise, the symbols in the libraries would need to be modified.
this is not portable to windows.
First thing's first, if you are going to be wrapping up a C API in C++ code, you should hide that dependency behind a compilation firewall. This is to (1) avoid polluting the global namespace with the names from the C API, and (2) freeing the user-code from the dependency to the third-party headers. In this example, a rather trivial modification can be done to isolate the dependency to the C APIs. You should do this:
// In NFoo.h:
#include "Foo.h"
class NFoo : public Foo
{
public:
virtual void foo(void);
};
// In NFoo.cpp:
#include "NFoo.h"
#include <nfoo.h>
void NFoo::foo(void) {
::foo(); // calling foo from the nfoo C-API
}
The point of the above is that the C API header, <nfoo.h>, is only included in the cpp file, not in the header file. This means that user-code will not need to provide the C API headers in order to compile code that uses your library, nor will the global namespace names from the C API risk clashing with anything else being compiled. Also, if your C API (or any other external dependency for that matter) requires creating a number of things (e.g., handles, objects, etc.) when using the API, then you can also wrap them in a PImpl (pointer to a forward-declared implementation class that is only declared-defined in the cpp file) to achieve the same isolation of the external dependency (i.e., a "compilation firewall").
Now, that the basic stuff is out of the way, we can move to the issue at hand: simultaneously linking to two C APIs with name-clashing symbols. This is a problem and there is no easy way out. The compilation firewall technique above is really about isolating and minimizing dependencies during compilation, and by that, you could easily compile code that depends on two APIs with conflicting names (which isn't true in your version), however, you will still be hit hard with ODR (One Definition Rule) errors when reaching the linking phase.
This thread has a few useful tricks to resolving C API name conflicts. In summary, you have the following choices:
If you have access to static libraries (or object files) for at least one of the two C APIs, then you can use a utility like objcopy (in Unix/Linux) to add a prefix to all the symbols in that static library (object files), e.g., with the command objcopy --prefix-symbols=libn_ libn.o to prefix all the symbols in libn.o with libn_. Of course, this implies that you will need to add the same prefix to the declarations in the API's header file(s) (or make a reduced version with only what you need), but this is not a problem from a maintenance perspective as long as you have a proper compilation firewall in place for that external dependency.
If you don't have access to static libraries (or object files) or don't want to do this above (somewhat troublesome) approach, you will have to go with a dynamic library. However, this isn't as trivial as it sounds (and I'm not even gonna go into the topic of DLL Hell). You must use dynamic loading of the dynamic link library (or shared-object file), as opposed to the more usual static loading. That is, you must use the LoadLibrary / GetProcAddress / FreeLibrary (for Windows) and the dlopen / dlsym / dlclose (all Unix-like OSes). This means that you have to individually load and set the function-pointer address for each function that you wish to use. Again, if the dependencies are properly isolated in the code, this is going to be just a matter of writing all this repetitive code, but not much danger involved here.
If your uses of the C APIs is much simpler than the C APIs themselves (i.e., you use only a few functions out of hundreds of functions), it might be a lot easier for you to create two dynamic libraries, one for each C API, that exports only the limited subset of functions, giving them unique names, that wrap calls to the C API. Then, you main application or library can be link to those two dynamic libraries directly (statically loaded). Of course, if you need to do that for all the functions in that C API, then there is no point in going through all this trouble.
So, you can choose what seems more reasonable or feasible for you, there is no doubt that it will require quite a bit a manual work to fix this up.
if you only want to access one library implementation at a time, a natural way to go about it is as a dynamic library
in Windows that also works for accessing two or more library implementations at a time, because Windows dynamic libraries provide total encapsulation of whatever's inside
IIUC ifdef is what you need
put #define _NFOO
in the nfoo lib and #define XFOO in xfoo lib.
Also remember if nfoo lib and xfoo lib both have a function called Foo then there will be error during compilation. To avoid this GCC/G++ uses function overloading through name mangling.
you can then check if xfoo is linked using ifdefs
#ifdef XFOO
//call xfoo's foo()
#endif
A linker cannot distinguish between two different definitions of the same symbol name, so if you're trying to use two functions with the same name you'll have to separate them somehow.
The way to separate them is to put them in dynamic libraries. You can choose which things to export from a dynamic library, so you can export the wrappers while leaving the underlying API functions hidden. You can also load the dynamic library at runtime and bind to symbols one at a time, so even if the same name is define in more than one they won't interfere with each other.