Related
I am trying to implement some unit tests for a C++ library that does not use OO (all functions are declared at namespace level)
For that purpose, I am trying to create a test binary that mocks (simulate) some functions.
I have achieved the above for functions that I call directly, but I have been unable to replace the calls that the library's functions do. The example below explains this:
Production code
Lets suppose this is the production code, the one that uses the real functions instead of the simulated ones:
CameraHandler.H
namespace Cam {
int myFunc();
int myFunc2();
}
CameraHandler.cpp
#include "CameraHandler.h"
using namespace Cam;
int Cam::myFunc() {
// Imagine this is the function I want to simulate with a mock
// Its mangled name is _ZN3Cam6myFuncEv
return 1;
}
int Cam::myFunc2(){
return Cam::myFunc() + 11;
}
Testing code
This is the code for the unit testing. As you can see in the Makefile, it generates a binary called testsMain.
CameraHandlerMock.h
extern "C" {
int __wrap__ZN3Cam6myFuncEv(); // mangled name of Cam::myFunc(), with the __wrap_ prefix.
}
CameraHandlerMock.cpp
#include "CameraHandlerMock.h"
int __wrap__ZN3Cam6myFuncEv(){
// As you can see, the mocked function returns 999 instead of 1.
return 999;
}
UnitTestsMain.cpp
#include <iostream>
#include <typeinfo>
#include "CameraHandler.h"
#include "CameraHandlerMock.h"
extern "C" int _ZN3Cam6myFuncEv();
int main(){
std::cout << Cam::myFunc() << std::endl;
std::cout << Cam::myFunc2() << std::endl;
return 0;
}
The Makefile
WRAP=-Wl,--wrap,_ZN3Cam6myFuncEv
all: production unitTests
production: // does not matter for this example
g++ main.cpp CameraHandler.cpp -o main
unitTests:
g++ ${WRAP} UnitTestsMain.cpp CameraHandlerMock.cpp CameraHandler.cpp -o testsMain
The problem
If I execute the testsMain program, I obtain the following result:
999 // call to Cam::myFunc()
12 // Cam::myFunc2(), which is Cam::myFunc() + 11.
Taking into account that Cam::myFunc2() calls to Cam::myFunc1(), and I have replaced it by __wrap__ZN3Cam6myFuncEv, what I expect is that t he result of calling Cam::myFunc2() is 999 + 11 = 1010. Nevertheless, Cam::myFunc2() is still calling the non-wrapped Cam::myFunc1(), so the result is 12.
Is there any way to wrap functions that are internally called by the library I want to test?
Let's lint a little bit of fluff first. In UnitTestsMain.cpp,
the declaration:
extern "C" int _ZN3Cam6myFuncEv();
is redundant. It simply instructs the C++ compiler that references to the function
of that prototype whose mangled name is _ZN3Cam6myFuncEv are references to
an externally defined function of that name. This is exactly the same information,
just expressed differently, that that the compiler has already got from:
namespace Cam {
int myFunc();
...
}
when it #include-ed CameraHandler.h, because _ZN3Cam6myFuncEv() is the mangled
form of Cam::myFunc. The extern "C" redeclaration of Cam::myFunc is harmless
but contributes nothing either to compilation or linkage.
On to the main question: Why does your mock
int __wrap__ZN3Cam6myFuncEv() get called instead of int Cam::myFunc in UnitTestsMain.cpp:
int main(){
std::cout << Cam::myFunc() << std::endl;
std::cout << Cam::myFunc2() << std::endl;
return 0;
}
as you want; but your mock is not called for int Cam::myFunc in CameraHandler.cpp:
int Cam::myFunc2(){
return Cam::myFunc() + 11;
}
The answer lies in the documentation of the --wrap linker option:
--wrap=symbol
Use a wrapper function for symbol. Any undefined reference to symbol will be
resolved to __wrap_symbol. Any undefined reference to __real_symbol will be
resolved to symbol.
Maybe you read it and didn't grok the significance of undefined reference.
This means that when --wrap=symbol is in effect, and the linker applies it
to an object file containing undefined references to symbol, it will replace them
with references to __wrap_symbol, and undefined references to __real_symbol,
in that object file, will be replaced with symbol.
Now in UnitTestsMain.o, compiled from UnitTestsMain.cpp, the references to both Cam::myFunc()
and Cam::myFunc2() are undefined. These functions are both defined in CameraHandler.cpp,
compiled in CameraHandler.o.
Therefore in the linkage of UnitTestsMain.o, --wrap ZN3Cam6myFuncEv will take effect and
replace the call to Cam::myFunc ( = ZN3Cam6myFuncEv) with a call to __wrap_ZN3Cam6myFuncEv.
The call to Cam::myFunc2() ( = ZN3Cam7myFunc2Ev) is not wrapped and is unaffected: it will be
resolved to the definition to be found in CameraHandler.o
But in the linkage of CameraHandler.o, both functions are defined, so --wrap has
no effect. When Cam::myFunc2() calls Cam::myFunc(), it calls ZN3Cam6myFuncEv, not
__wrap_ZN3Cam6myFuncEv.
That explains why the program outputs:
999
12
and not:
999
1010
Can you make your mocking work as expected?
Yes. You just have to ensure that every call to Cam::myFunc that you want to be
mocked is compiled into an object file that does not contain the (real) definition
of Cam::myFunc. The obvious way to do that is to define Cam::myFunc in its own
source file. Here's your example fixed:
CameraHandler.h
#ifndef CAMERAHANDLER_H
#define CAMERAHANDLER_H
namespace Cam {
int myFunc();
int myFunc2();
}
#endif
CameraHandlerMock.h
#ifndef CAMERAHANDLERMOCK_H
#define CAMERAHANDLERMOCK_H
extern "C" {
int __wrap__ZN3Cam6myFuncEv();
}
#endif
CameraHandler_myFunc.cpp
#include "CameraHandler.h"
using namespace Cam;
int Cam::myFunc() {
return 1;
}
CameraHandler_myFunc2.cpp
#include "CameraHandler.h"
using namespace Cam;
int Cam::myFunc2(){
return Cam::myFunc() + 11;
}
CameraHandlerMock.cpp
#include "CameraHandlerMock.h"
int __wrap__ZN3Cam6myFuncEv() {
return 999;
}
UnitTestsMain.cpp
#include <iostream>
#include "CameraHandler.h"
#include "CameraHandlerMock.h"
int main(){
std::cout << Cam::myFunc() << std::endl;
std::cout << Cam::myFunc2() << std::endl;
return 0;
}
Makefile
SRCS := UnitTestsMain.cpp CameraHandler_myFunc.cpp \
CameraHandler_myFunc2.cpp CameraHandlerMock.cpp
OBJS := $(SRCS:.cpp=.o)
LDFLAGS := -Wl,--wrap,_ZN3Cam6myFuncEv
.PHONY: unitTests clean
unitTests: testsMain
testsMain: $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
UnitTestsMain: CameraHandler.h CameraHandlerMock.h
CameraHandler_Func.o CameraHandler_Func2.o: CameraHandler.h
CameraHandlerMock.o: CameraHandlerMock.h
clean:
rm -f $(OBJS) testsMain
(Your production build is not considered at all in this example makefile)
With this, the test build runs like:
$ make
g++ -c -o UnitTestsMain.o UnitTestsMain.cpp
g++ -c -o CameraHandler_myFunc.o CameraHandler_myFunc.cpp
g++ -c -o CameraHandler_myFunc2.o CameraHandler_myFunc2.cpp
g++ -c -o CameraHandlerMock.o CameraHandlerMock.cpp
g++ -Wl,--wrap,_ZN3Cam6myFuncEv -o testsMain UnitTestsMain.o \
CameraHandler_myFunc.o CameraHandler_myFunc2.o CameraHandlerMock.o
and testsMain does what you expect:
$ ./testsMain
999
1010
You can simplify both source files and the makefile somewhat if you rewrite
CameraHandlerMock.cpp as just:
extern "C" {
int __wrap__ZN3Cam6myFuncEv() {
return 999;
}
}
Then you have no need for the mock header file CameraHandlerMock.h at all.
If you have a lot of functions you need to mock in this low-level way, it
may get tedious to define each one in its own source file. You may be aware
that there are higher-level, framework-supported mocking options, e.g. googlemock,
that have rich mocking capabilities and don't entail this tedium. It's fair to say, however, that they may
replace it with more complicated kinds of tedium.
I have a problem in C++.
I've created a function called execute
int* execute(int tab[], int n)
{
for (int i = 0; i<n; i++)
{
for (int j = 0; j < n-1; j++)
{
if (tab[j] > tab[j+1])
{
int tmp = tab[j];
tab[j] = tab[j+1];
tab[j+1] = tmp;
}
}
}
return tab;
}
So, this is simple BubbleSort function. I have this function in file BubbleSortAlgorithm.cpp.
So, in main function of my program, I check if libBubbleSortAlgorithm.so exist. If not, then I must create this lib. This lib is created via popen. So I've ended up with file libBubbleSortAlgorithm.so. If I run command
nm libBubbleSortAlgorithm.so | c++filt
then I get something like this.
0000000000000ed0 T execute(int*, int)
U dyld_stub_binder
I presume this is ok. So, next in main program, I load this .so file in my program with dlopen and call this function like this
void *handle = dlopen(buff, RTLD_LAZY);
if (handle)
{
execute = dlsym(handle, "execute");
int tab[5] = { 5, 2, 4, 7, 1 };
int x = 5;
execute(tab, x);
}
But before main I've also wrote this
#ifdef __cplusplus
extern "C" {
#endif
void (*execute)(int*, int);
#ifdef __cplusplus
}
#endif
So, in Xcode7, I get this error:
/Users/Tadej/Documents/Development/ALGatorC_final/ALGatorC/ALGatorC/main.cpp:96:49: Assigning to 'void (*)(int *, int)' from incompatible type 'void *'
Thank you in advance for help.
Regards,
golobich
Edit: I've changed code like this:
#ifdef __cplusplus
extern "C" {
#endif
int* (*execute)(int*, int);
#ifdef __cplusplus
}
#endif
execute = (int*(*)(int*, int))dlsym(handle, "execute");
int tab[5] = { 5, 2, 4, 7, 1 };
int x = 5;
int *xs = execute(tab, x);
for (int i = 0; i<5; i++)
{
std::cout << xs[i] << ", ";
}
So, now, I have problem at runtime. At execute(tab, x), Xcode complain and say this: EXC_BAD_ACCESS(code=1, address=0x0). So, problem is that execute is NULL. Any help? :)
You can safely cast the result.
dlsym just returns a (function) pointer, but does not know (nor it can) know the actual signature of your function. Only client code (your) can know that.
Cast can be done like this:
typedef int *(*execute_t)(int, int) ;
...
execute = (execute_t *)dlsym(handle, "execute");
And keep in mind what #molbdnilo says about function to be declared 'extern "C". This has to be done in libary code, not on client side
extern "C" int* execute(int tab[], int n)
{
for (int i = 0; i<n; i++)
{
....
The function in the library wasn't compiled with extern "C" linkage, so the name has C++ name-mangling in the library.
Because of this, dlsym can't find the name "execute" and returns a null pointer.
Either add extern "C" in the library, or dlsym the actual symbol as shown by nm without piping its output through c++filt.
Or build your library from C code.
I had same Problem but I did the following, without using the extern "C" keyword. Let say, we create a directory in Users/you/Desktop/FooProject and we write our shared library foo.cpp :
#ifndef FOO_H
#define FOO_H
int sum(int x, int y)
{
return x+y;
}
int subs( int x, int y)
{
return x-y;
}
#endif //FOO_H
We create the share library from foo.cpp:
g++ -dynamiclib foo.cpp -o libfoo.dylib
Now we would like to write a program that gets the function pointers to our library in the same directory /Users/You/FooProject/. For that we use dlopen(), dlsym() and dlclose() functions.
Because of the C++ name-mangling (used for function overloading ) our function names will differ from the ones that we have written on foo.cpp.
If we run objdump -t libfoo.dylib we get ( on my machine) this output:
libfoo.dylib: file format Mach-O 64-bit x86-64
SYMBOL TABLE:
0000000000000f80 g F __TEXT,__text __Z3sumii
0000000000000fa0 g F __TEXT,__text __Z4subsii
0000000000000000 *UND* dyld_stub_binder
Here is the tricky thing to take in count. Notice the two underscore lines before the names __Z3sumii and __Z4subsii. The actual names of the functions that we want to pull are just with one underscore instead of two. The names of the functions are _Z3sumii and _Z4subsii with only one underscore.
If you try to pull out the functions on dlsym() passing the name with the two underscores or the original names it will return NULL.
Wrong:
int (*sum)(int, int);
sum = dlsym(foo_lib_handle,"__Z3sumii");//two underscores and no casting
or
int (*sum)(int, int);
sum = dlsym(foo_lib_handle,"sum"); //the name demangled and no casting
Correct:
int (*sum)(int, int);
sum = ( int(*)(int, int) ) dlsym(foo_lib_handle,"_Z3sumii");
Because the dlsym returns a void pointer and the signatura expected is different we need to cast it appropriately.
Now that we know the names we need. We can write the code to pull out the function pointers for the dylib, called pullout.cpp:
#include <dlfcn.h>
#include <iostream>
int main( )
{
//function pointers for the pulled functions
int (*sum)(int, int);
int (*subs)(int, int);
// open the shared library
void* foo_lib_handle = dlopen("libfoo.dylib", RTLD_LAZY | RTLD_GLOBAL);
if(!foo_lib_handle)
{
std::cout << "problemo loading dylib" << std::endl;
return 1;
}
//notice the casting and the name "_Z3sumii" instead of "__Z3sumii" and the same for subs
sum = ( int(*)(int, int) ) dlsym(foo_lib_handle,"_Z3sumii");
subs = ( int(*)(int,int ) ) dlsym(foo_lib_handle,"_Z4subsii");
if( sum == NULL || subs == NULL )
{
std::cout << "functions pointers are null" << std::endl;
return 1;
}
std::cout << "calling sum(8,8) = " << sum(8,8) << '\n';
std::cout << "calling subs(18,8) = "<< subs(18,8) <<'\n';
//close the library
dlclose(foo_lib_handle);
return 0;
}
Compile pullout.cpp:
g++ -c pullout.cpp
To Link the pullout.o file generated, we can use several approaches :
We can use the -L to specify the path where to search the lib, and -l :
g++ pullout.o -L. -lfoo -o pulloutFoo
The -l option is expanded as -libfoo.dylib. Is important to notice that the default search path for gcc are:
/usr/local/lib
/usr/lib
Because of this, we need to use the -L option followed by the path. In our case we use the current directory.
Second option is to specify the full path and the name of the lib, so we do not have to use te -L, and -l options.
g++ pullout.o libfoo.dylib -o pullFoo
Third option, put the shared library into one of the common directories like /usr/local/lib . Then we would just do :
g++ pullout.o -lfoo -o pullFoo
If we run it:
$ ./pullFoo
calling sum(8,8) 16
calling subs(18,8) 10
Extra:
For runtime problems, see install names for mac os here: dynamic libraries and macOs and here stakoverflow.
This feels like a noob question, so if it's a dupe, please point me to the right location :)
I tried including a DLL written in C into a C++ program. It didn't work; gcc said
test.cpp: xxx: error: too many arguments to function.
Here's a minimal working example:
Wrapper for DLL functions:
/* myWrapper.h */
#ifndef _MYWRAPPER_H
#define _MYWRAPPER_H
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
extern FARPROC EXPORTED_functionNameP;
int GetDLLpointers();
#ifdef __cplusplus
}
#endif
#endif
Implementation thereof:
/* myWrapper.c */
#include <windows.h>
#include "myHeader.h"
#ifdef __cplusplus
extern "C" {
#endif
HINSTANCE drvsHANDLE;
extern FARPROC EXPORTED_functionNameP;
int GetDLLpointers()
{
static int result;
drvsHANDLE = LoadLibrary("myLibrary.dll");
if (drvsHANDLE == NULL) return (result=0);
EXPORTED_functionNameP = GetProcAddress(
drvsHANDLE, "originalFunctionName");
if (EXPORTED_functionNameP == NULL) return (result = 0);
return (result = 1);
}
#ifdef __cplusplus
}
#endif
Naturally, I haven't written these nor the library myself, and preferably, they should all stay untouched. I did however add the extern "C" lines.
Then, my main file:
// my Main
#include <windows.h>
#include "myHeader.h"
int main(int argc, char **argv)
{
int arg = 1;
EXPORTED_functionNameP(arg);
return 0;
}
Build commands:
gcc -I. -c -o myHeader.o myHeader.c -L. -lmyLibrary
g++ -I. -o main.exe myMain.cpp myHeader.o -L. -lmyLibrary
It works fine if I rewrite my main.cpp into valid C and compile with gcc instead of g++.
I tried changing extern "C" into extern "C++" to no avail, I tried all permutations or gcc and g++ for the two build commands, nothing.
I know it's something to do with name mangling, but I thought gcc would take care of that when you include the extern "C" lines...Can someone please explain what I'm missing here?
In case it matters --
Windows XP Pro (will be Win7 later on)
(MinGW) gcc 4.6.2
I know this is a very old question, but I am having exactly the same issues but in relation to writing a generic wrapper template for wrapping calls to LoadLibrary() and GetProcAddress()
Taking https://blog.benoitblanchon.fr/getprocaddress-like-a-boss/ as inspiration, it looks like he is taking FARPROC as a kind of "void* for Windows functions" and then casting it to the correct type subsequently.
I needed to tweak that code a little to work for me, and reproduce it here:
class ProcPtr
{
public:
explicit ProcPtr(FARPROC ptr) : m_ptr(ptr) {}
template <typename T>
operator T* () const { return reinterpret_cast<T*>(m_ptr); }
private:
FARPROC m_ptr;
};
class DllHelper
{
public:
explicit DllHelper(LPCTSTR filename) : m_module(LoadLibrary(filename)) {}
~DllHelper() { FreeLibrary(m_module); }
ProcPtr operator[](LPCSTR proc_name) const
{
return ProcPtr(::GetProcAddress(m_module, proc_name));
}
private:
HMODULE m_module;
};
So, with that helper code now available we can use it to write a wrapper class that encapsulates several functions in the Advapi32 library:
class Advapi32
{
public:
Advapi32() : m_dll(TEXT("Advapi32"))
{
getUserName = m_dll["GetUserNameA"];
openSCManager = m_dll["OpenSCManagerA"];
bogusFunction = m_dll["BogusFunctionThatDoesNotExist"];
}
decltype(GetUserNameA)* getUserName;
decltype(OpenSCManagerA)* openSCManager;
decltype(GetWindowsDirectoryA)* bogusFunction;
private:
DllHelper m_dll;
};
bogusFunction is a function with the same signature as GetWindowsDirectoryA but which doesn't exist in Advapi32. This is what I was trying to achieve - graceful fallback on an older OS which might not have a certain function.
So, finally a test app...
int main()
{
Advapi32 advapi32;
auto func1 = advapi32.getUserName;
if (func1)
{
TCHAR infoBuf[256];
DWORD bufCharCount = sizeof(infoBuf);
if (func1(infoBuf, &bufCharCount))
{
std::cout << "Username: " << infoBuf << std::endl;
}
}
auto func2 = advapi32.openSCManager;
if (func2)
{
SC_HANDLE handle = func2(NULL, NULL, SC_MANAGER_CONNECT);
if (handle)
{
std::cout << "opened SC Manager" << std::endl;
}
}
auto func3 = advapi32.bogusFunction;
if (func3)
{
std::cerr << "This should not happen!" << std::endl;
}
else
{
std::cout << "Function not supported" << std::endl;
}
}
Output:
Username: TestAccount
opened SC Manager
Function not supported
Note: This was compiled as a Windows 32-bit console application with MBCS rather than Unicode, under VS2019 with the VS2015_XP toolset, since that is what I am needing to target (don't ask).
The FARPROC type is a function pointer for a function that takes no parameters. You should declare EXPORTED_functionNameP like so (replacing void with whatever the function really returns):
extern void (*EXPORTED_functionNameP)(int);
And initialize it like so (the returned value from GetProcAddress() pretty much always needs to be cast to the correct type):
EXPORTED_functionNameP = (void (*)(int)) GetProcAddress(drvsHANDLE, "originalFunctionName");
A typedef for the funciton type might make things a bit more readable.
There is a difference between C and C++.
int (FAR WINAPI * FARPROC) ()
In C, the FARPROC declaration indicates a callback function that has an unspecified parameter list. In C++, however, the empty parameter list in the declaration indicates that a function has no parameters.
The MSDN page on CallWindowProc explains a bit more.
After a quick Google search, it seems that FARPROC is defined as this:
typedef int (FAR WINAPI *FARPROC)();
That is, FARPROC is a function that returns an int and takes no arguments. So you can't use it for any other case.
Instead declare EXPORTED_functionNameP like this:
extern void (*EXPORTED_functionNameP)(int);
Now EXPORTED_functionNameP is a pointer to a function that takes an int argument and returns no value.
It is because of FARPROC is defined as:
int (FAR WINAPI * FARPROC) ()
So you can not pass any parameters to such function in C++. For fix it you should define EXPORTED_functionNameP as pointer to function with equal semantics as defined in DLL-library. For example:
typedef (void* EXPORTED_functionNameP)(int value);
EXPORTED_functionNameP ExportedFns;
...
ExportedFns = GetProcAddress(drvsHANDLE, "originalFunctionName");
FARPROC is defined as
typedef int (FAR WINAPI *FARPROC)();
When you pass an additional argument although the argument list of the prototype is empty you get the error.
You need a proper prototype definition for PORTED_functionNameP and cas the result from GetProcAddress to that type in your GetDLLPopinters functions.
C++ is a static, compiled language, templates are resolved during compile time and so on...
But is it possible to create a function during runtime, that is not described in the source code and has not been converted to machine language during compilation, so that a user can throw at it data that has not been anticipated in the source?
I am aware this cannot happen in a straightforward way, but surely it must be possible, there are plenty of programing languages that are not compiled and create that sort of stuff dynamically that are implemented in either C or C++.
Maybe if factories for all primitive types are created, along with suitable data structures to organize them into more complex objects such as user types and functions, this is achievable?
Any info on the subject as well as pointers to online materials are welcome. Thanks!
EDIT: I am aware it is possible, it is more like I am interested in implementation details :)
Yes, of course, without any tools mentioned in the other answers, but simply using the C++ compiler.
just follow these steps from within your C++ program (on linux, but must be similar on other OS)
write a C++ program into a file (e.g. in /tmp/prog.cc), using an ofstream
compile the program via system("c++ /tmp/prog.cc -o /tmp/prog.so -shared -fPIC");
load the program dynamically, e.g. using dlopen()
You can also just give the bytecode directly to a function and just pass it casted as the function type as demonstrated below.
e.g.
byte[3] func = { 0x90, 0x0f, 0x1 }
*reinterpret_cast<void**>(&func)()
Yes, JIT compilers do it all the time. They allocate a piece of memory that has been given special execution rights by the OS, then fill it with code and cast the pointer to a function pointer and execute it. Pretty simple.
EDIT: Here's an example on how to do it in Linux: http://burnttoys.blogspot.de/2011/04/how-to-allocate-executable-memory-on.html
Below an example for C++ runtime compilation based on the method mentioned before (write code to output file, compile via system(), load via dlopen() and dlsym()). See also the example in a related question. The difference here is that it dynamically compiles a class rather than a function. This is achieved by adding a C-style maker() function to the code to be compiled dynamically. References:
https://www.linuxjournal.com/article/3687
http://www.tldp.org/HOWTO/C++-dlopen/thesolution.html
The example only works under Linux (Windows has LoadLibrary and GetProcAddress functions instead), and requires the identical compiler to be available on the target machine.
baseclass.h
#ifndef BASECLASS_H
#define BASECLASS_H
class A
{
protected:
double m_input; // or use a pointer to a larger input object
public:
virtual double f(double x) const = 0;
void init(double input) { m_input=input; }
virtual ~A() {};
};
#endif /* BASECLASS_H */
main.cpp
#include "baseclass.h"
#include <cstdlib> // EXIT_FAILURE, etc
#include <string>
#include <iostream>
#include <fstream>
#include <dlfcn.h> // dynamic library loading, dlopen() etc
#include <memory> // std::shared_ptr
// compile code, instantiate class and return pointer to base class
// https://www.linuxjournal.com/article/3687
// http://www.tldp.org/HOWTO/C++-dlopen/thesolution.html
// https://stackoverflow.com/questions/11016078/
// https://stackoverflow.com/questions/10564670/
std::shared_ptr<A> compile(const std::string& code)
{
// temporary cpp/library output files
std::string outpath="/tmp";
std::string headerfile="baseclass.h";
std::string cppfile=outpath+"/runtimecode.cpp";
std::string libfile=outpath+"/runtimecode.so";
std::string logfile=outpath+"/runtimecode.log";
std::ofstream out(cppfile.c_str(), std::ofstream::out);
// copy required header file to outpath
std::string cp_cmd="cp " + headerfile + " " + outpath;
system(cp_cmd.c_str());
// add necessary header to the code
std::string newcode = "#include \"" + headerfile + "\"\n\n"
+ code + "\n\n"
"extern \"C\" {\n"
"A* maker()\n"
"{\n"
" return (A*) new B(); \n"
"}\n"
"} // extern C\n";
// output code to file
if(out.bad()) {
std::cout << "cannot open " << cppfile << std::endl;
exit(EXIT_FAILURE);
}
out << newcode;
out.flush();
out.close();
// compile the code
std::string cmd = "g++ -Wall -Wextra " + cppfile + " -o " + libfile
+ " -O2 -shared -fPIC &> " + logfile;
int ret = system(cmd.c_str());
if(WEXITSTATUS(ret) != EXIT_SUCCESS) {
std::cout << "compilation failed, see " << logfile << std::endl;
exit(EXIT_FAILURE);
}
// load dynamic library
void* dynlib = dlopen (libfile.c_str(), RTLD_LAZY);
if(!dynlib) {
std::cerr << "error loading library:\n" << dlerror() << std::endl;
exit(EXIT_FAILURE);
}
// loading symbol from library and assign to pointer
// (to be cast to function pointer later)
void* create = dlsym(dynlib, "maker");
const char* dlsym_error=dlerror();
if(dlsym_error != NULL) {
std::cerr << "error loading symbol:\n" << dlsym_error << std::endl;
exit(EXIT_FAILURE);
}
// execute "create" function
// (casting to function pointer first)
// https://stackoverflow.com/questions/8245880/
A* a = reinterpret_cast<A*(*)()> (create)();
// cannot close dynamic lib here, because all functions of the class
// object will still refer to the library code
// dlclose(dynlib);
return std::shared_ptr<A>(a);
}
int main(int argc, char** argv)
{
double input=2.0;
double x=5.1;
// code to be compiled at run-time
// class needs to be called B and derived from A
std::string code = "class B : public A {\n"
" double f(double x) const \n"
" {\n"
" return m_input*x;\n"
" }\n"
"};";
std::cout << "compiling.." << std::endl;
std::shared_ptr<A> a = compile(code);
a->init(input);
std::cout << "f(" << x << ") = " << a->f(x) << std::endl;
return EXIT_SUCCESS;
}
output
$ g++ -Wall -std=c++11 -O2 -c main.cpp -o main.o # c++11 required for std::shared_ptr
$ g++ -ldl main.o -o main
$ ./main
compiling..
f(5.1) = 10.2
Have a look at libtcc; it is simple, fast, reliable and suits your need. I use it whenever I need to compile C functions "on the fly".
In the archive, you will find the file examples/libtcc_test.c, which can give you a good head start.
This little tutorial might also help you: http://blog.mister-muffin.de/2011/10/22/discovering-tcc/
#include <stdlib.h>
#include <stdio.h>
#include "libtcc.h"
int add(int a, int b) { return a + b; }
char my_program[] =
"int fib(int n) {\n"
" if (n <= 2) return 1;\n"
" else return fib(n-1) + fib(n-2);\n"
"}\n"
"int foobar(int n) {\n"
" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
" return 1337;\n"
"}\n";
int main(int argc, char **argv)
{
TCCState *s;
int (*foobar_func)(int);
void *mem;
s = tcc_new();
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
tcc_compile_string(s, my_program);
tcc_add_symbol(s, "add", add);
mem = malloc(tcc_relocate(s, NULL));
tcc_relocate(s, mem);
foobar_func = tcc_get_symbol(s, "foobar");
tcc_delete(s);
printf("foobar returned: %d\n", foobar_func(32));
free(mem);
return 0;
}
Ask questions in the comments if you meet any problems using the library!
In addition to simply using an embedded scripting language (Lua is great for embedding) or writing your own compiler for C++ to use at runtime, if you really want to use C++ you can just use an existing compiler.
For example Clang is a C++ compiler built as libraries that could be easily embedded in another program. It was designed to be used from programs like IDEs that need to analyze and manipulate C++ source in various ways, but using the LLVM compiler infrasructure as a backend it also has the ability to generate code at runtime and hand you a function pointer that you can call to run the generated code.
Clang
LLVM
Essentially you will need to write a C++ compiler within your program (not a trivial task), and do the same thing JIT compilers do to run the code. You were actually 90% of the way there with this paragraph:
I am aware this cannot happen in a straightforward way, but surely it
must be possible, there are plenty of programing languages that are
not compiled and create that sort of stuff dynamically that are
implemented in either C or C++.
Exactly--those programs carry the interpreter with them. You run a python program by saying python MyProgram.py--python is the compiled C code that has the ability to interpret and run your program on the fly. You would need do something along those lines, but by using a C++ compiler.
If you need dynamic functions that badly, use a different language :)
A typical approach for this is to combine a C++ (or whatever it's written on) project with scripting language.
Lua is one of the top favorites, since it's well documented, small, and has bindings for a lot of languages.
But if you are not looking into that direction, perhaps you could think of making a use of dynamic libraries?
Yes - you can write a compiler for C++, in C++, with some extra features - write your own functions, compile and run automatically (or not)...
Have a look into ExpressionTrees in .NET - I think this is basically what you want to achieve. Create a tree of subexpressions and then evaluate them. In an object-oriented fashion, each node in the might know how to evaluate itself, by recursion into its subnodes. Your visual language would then create this tree and you can write a simple interpreter to execute it.
Also, check out Ptolemy II, as an example in Java on how such a visual programming language can be written.
You could take a look at Runtime Compiled C++ (or see RCC++ blog and videos), or perhaps try one of its alternatives.
Expanding on Jay's answer using opcodes, the below works on Linux.
Learn opcodes from your compiler:
write own myfunc.cpp, e.g.
double f(double x) { return x*x; }
compile with
$ g++ -O2 -c myfunc.cpp
disassemble function f
$ gdb -batch -ex "file ./myfunc.o" -ex "set disassembly-flavor intel" -ex "disassemble/rs f"
Dump of assembler code for function _Z1fd:
0x0000000000000000 <+0>: f2 0f 59 c0 mulsd xmm0,xmm0
0x0000000000000004 <+4>: c3 ret
End of assembler dump.
This means the function x*x in assembly is mulsd xmm0,xmm0, ret and in machine code f2 0f 59 c0 c3.
Write your own function in machine code:
opcode.cpp
#include <cstdlib> // EXIT_FAILURE etc
#include <cstdio> // printf(), fopen() etc
#include <cstring> // memcpy()
#include <sys/mman.h> // mmap()
// allocate memory and fill it with machine code instructions
// returns pointer to memory location and length in bytes
void* gencode(size_t& length)
{
// machine code
unsigned char opcode[] = {
0xf2, 0x0f, 0x59, 0xc0, // mulsd xmm0,xmm0
0xc3 // ret
};
// allocate memory which allows code execution
// https://en.wikipedia.org/wiki/NX_bit
void* buf = mmap(NULL,sizeof(opcode),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
// copy machine code to executable memory location
memcpy(buf, opcode, sizeof(opcode));
// return: pointer to memory location with executable code
length = sizeof(opcode);
return buf;
}
// print the disassemby of buf
void print_asm(const void* buf, size_t length)
{
FILE* fp = fopen("/tmp/opcode.bin", "w");
if(fp!=NULL) {
fwrite(buf, length, 1, fp);
fclose(fp);
}
system("objdump -D -M intel -b binary -mi386 /tmp/opcode.bin");
}
int main(int, char**)
{
// generate machine code and point myfunc() to it
size_t length;
void* code=gencode(length);
double (*myfunc)(double); // function pointer
myfunc = reinterpret_cast<double(*)(double)>(code);
double x=1.5;
printf("f(%f)=%f\n", x,myfunc(x));
print_asm(code,length); // for debugging
return EXIT_SUCCESS;
}
compile and run
$ g++ -O2 opcode.cpp -o opcode
$ ./opcode
f(1.500000)=2.250000
/tmp/opcode.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: f2 0f 59 c0 mulsd xmm0,xmm0
4: c3 ret
The simplest solution available, if you're not looking for performance is to embed a scripting language interpreter, e.g. for Lua or Python.
It worked for me like this. You have to use the -fpermissive flag.
I am using CodeBlocks 17.12.
#include <cstddef>
using namespace std;
int main()
{
char func[] = {'\x90', '\x0f', '\x1'};
void (*func2)() = reinterpret_cast<void*>(&func);
func2();
return 0;
}
In the new Go language, how do I call C++ code? In other words, how can I wrap my C++ classes and use them in Go?
Update: I've succeeded in linking a small test C++ class with Go
If you wrap you C++ code with a C interface you should be able to call your library with cgo (see the example of gmp in $GOROOT/misc/cgo/gmp).
I'm not sure if the idea of a class in C++ is really expressible in Go, as it doesn't have inheritance.
Here's an example:
I have a C++ class defined as:
// foo.hpp
class cxxFoo {
public:
int a;
cxxFoo(int _a):a(_a){};
~cxxFoo(){};
void Bar();
};
// foo.cpp
#include <iostream>
#include "foo.hpp"
void
cxxFoo::Bar(void){
std::cout<<this->a<<std::endl;
}
which I want to use in Go. I'll use the C interface
// foo.h
#ifdef __cplusplus
extern "C" {
#endif
typedef void* Foo;
Foo FooInit(void);
void FooFree(Foo);
void FooBar(Foo);
#ifdef __cplusplus
}
#endif
(I use a void* instead of a C struct so the compiler knows the size of Foo)
The implementation is:
//cfoo.cpp
#include "foo.hpp"
#include "foo.h"
Foo FooInit()
{
cxxFoo * ret = new cxxFoo(1);
return (void*)ret;
}
void FooFree(Foo f)
{
cxxFoo * foo = (cxxFoo*)f;
delete foo;
}
void FooBar(Foo f)
{
cxxFoo * foo = (cxxFoo*)f;
foo->Bar();
}
with all that done, the Go file is:
// foo.go
package foo
// #include "foo.h"
import "C"
import "unsafe"
type GoFoo struct {
foo C.Foo;
}
func New()(GoFoo){
var ret GoFoo;
ret.foo = C.FooInit();
return ret;
}
func (f GoFoo)Free(){
C.FooFree(unsafe.Pointer(f.foo));
}
func (f GoFoo)Bar(){
C.FooBar(unsafe.Pointer(f.foo));
}
The makefile I used to compile this was:
// makefile
TARG=foo
CGOFILES=foo.go
include $(GOROOT)/src/Make.$(GOARCH)
include $(GOROOT)/src/Make.pkg
foo.o:foo.cpp
g++ $(_CGO_CFLAGS_$(GOARCH)) -fPIC -O2 -o $# -c $(CGO_CFLAGS) $<
cfoo.o:cfoo.cpp
g++ $(_CGO_CFLAGS_$(GOARCH)) -fPIC -O2 -o $# -c $(CGO_CFLAGS) $<
CGO_LDFLAGS+=-lstdc++
$(elem)_foo.so: foo.cgo4.o foo.o cfoo.o
gcc $(_CGO_CFLAGS_$(GOARCH)) $(_CGO_LDFLAGS_$(GOOS)) -o $# $^ $(CGO_LDFLAGS)
Try testing it with:
// foo_test.go
package foo
import "testing"
func TestFoo(t *testing.T){
foo := New();
foo.Bar();
foo.Free();
}
You'll need to install the shared library with make install, then run make test. Expected output is:
gotest
rm -f _test/foo.a _gotest_.6
6g -o _gotest_.6 foo.cgo1.go foo.cgo2.go foo_test.go
rm -f _test/foo.a
gopack grc _test/foo.a _gotest_.6 foo.cgo3.6
1
PASS
Seems that currently SWIG is best solution for this:
https://www.swig.org/Doc4.0/Go.html
It supports inheritance and even allows to subclass C++ class with Go struct so when overridden methods are called in C++ code, Go code is fired.
Section about C++ in Go FAQ is updated and now mentions SWIG and no longer says "because Go is garbage-collected it will be unwise to do so, at least naively".
As of go1.2+, cgo automatically incorporates and compiles C++ code:
http://golang.org/doc/go1.2#cgo_and_cpp
You can't quite yet from what I read in the FAQ:
Do Go programs link with C/C++ programs?
There are two Go compiler implementations, gc (the 6g program and friends) and gccgo. Gc uses a different calling convention and linker and can therefore only be linked with C programs using the same convention. There is such a C compiler but no C++ compiler. Gccgo is a GCC front-end that can, with care, be linked with GCC-compiled C or C++ programs.
The cgo program provides the mechanism for a “foreign function interface” to allow safe calling of C libraries from Go code. SWIG extends this capability to C++ libraries.
I've created the following example based on Scott Wales' answer. I've tested it in macOS High Sierra 10.13.3 running go version go1.10 darwin/amd64.
(1) Code for library.hpp, the C++ API we aim to call.
#pragma once
class Foo {
public:
Foo(int value);
~Foo();
int value() const;
private:
int m_value;
};
(2) Code for library.cpp, the C++ implementation.
#include "library.hpp"
#include <iostream>
Foo::Foo(int value) : m_value(value) {
std::cout << "[c++] Foo::Foo(" << m_value << ")" << std::endl;
}
Foo::~Foo() { std::cout << "[c++] Foo::~Foo(" << m_value << ")" << std::endl; }
int Foo::value() const {
std::cout << "[c++] Foo::value() is " << m_value << std::endl;
return m_value;
}
(3) Code for library-bridge.h the bridge needed to expose a C API implemented in C++ so that go can use it.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void* LIB_NewFoo(int value);
void LIB_DestroyFoo(void* foo);
int LIB_FooValue(void* foo);
#ifdef __cplusplus
} // extern "C"
#endif
(4) Code for library-bridge.cpp, the implementation of the bridge.
#include <iostream>
#include "library-bridge.h"
#include "library.hpp"
void* LIB_NewFoo(int value) {
std::cout << "[c++ bridge] LIB_NewFoo(" << value << ")" << std::endl;
auto foo = new Foo(value);
std::cout << "[c++ bridge] LIB_NewFoo(" << value << ") will return pointer "
<< foo << std::endl;
return foo;
}
// Utility function local to the bridge's implementation
Foo* AsFoo(void* foo) { return reinterpret_cast<Foo*>(foo); }
void LIB_DestroyFoo(void* foo) {
std::cout << "[c++ bridge] LIB_DestroyFoo(" << foo << ")" << std::endl;
AsFoo(foo)->~Foo();
}
int LIB_FooValue(void* foo) {
std::cout << "[c++ bridge] LIB_FooValue(" << foo << ")" << std::endl;
return AsFoo(foo)->value();
}
(5) Finally, library.go, the go program calling the C++ API.
package main
// #cgo LDFLAGS: -L. -llibrary
// #include "library-bridge.h"
import "C"
import "unsafe"
import "fmt"
type Foo struct {
ptr unsafe.Pointer
}
func NewFoo(value int) Foo {
var foo Foo
foo.ptr = C.LIB_NewFoo(C.int(value))
return foo
}
func (foo Foo) Free() {
C.LIB_DestroyFoo(foo.ptr)
}
func (foo Foo) value() int {
return int(C.LIB_FooValue(foo.ptr))
}
func main() {
foo := NewFoo(42)
defer foo.Free() // The Go analog to C++'s RAII
fmt.Println("[go]", foo.value())
}
Using the following Makefile
liblibrary.so: library.cpp library-bridge.cpp
clang++ -o liblibrary.so library.cpp library-bridge.cpp \
-std=c++17 -O3 -Wall -Wextra -fPIC -shared
I can run the example program as follows:
$ make
clang++ -o liblibrary.so library.cpp library-bridge.cpp \
-std=c++17 -O3 -Wall -Wextra -fPIC -shared
$ go run library.go
[c++ bridge] LIB_NewFoo(42)
[c++] Foo::Foo(42)
[c++ bridge] LIB_NewFoo(42) will return pointer 0x42002e0
[c++ bridge] LIB_FooValue(0x42002e0)
[c++] Foo::value() is 42
[go] 42
[c++ bridge] LIB_DestroyFoo(0x42002e0)
[c++] Foo::~Foo(42)
Important
The comments above import "C" in the go program are NOT OPTIONAL. You must put them exactly as shown so that cgo knows which header and library to load, in this case:
// #cgo LDFLAGS: -L. -llibrary
// #include "library-bridge.h"
import "C"
Link to GitHub repo with the full example.
Looks it's one of the early asked question about Golang . And same time answers to never update . During these three to four years , too many new libraries and blog post has been out . Below are the few links what I felt useful .
SWIG and Go
Calling C++ Code From Go With SWIG
On comparing languages, C++ and Go
GoForCPPProgrammers
There's talk about interoperability between C and Go when using the gcc Go compiler, gccgo. There are limitations both to the interoperability and the implemented feature set of Go when using gccgo, however (e.g., limited goroutines, no garbage collection).
You're walking on uncharted territory here. Here is the Go example for calling C code, perhaps you can do something like that after reading up on C++ name mangling and calling conventions, and lots of trial and error.
If you still feel like trying it, good luck.
You might need to add -lc++ to the LDFlags for Golang/CGo to recognize the need for the standard library.
The problem here is that a compliant implementation does not need to put your classes in a compile .cpp file. If the compiler can optimize out the existence of a class, so long as the program behaves the same way without it, then it can be omitted from the output executable.
C has a standardized binary interface. Therefore you'll be able to know that your functions are exported. But C++ has no such standard behind it.
Funny how many broader issues this announcement has dredged up. Dan Lyke had a very entertaining and thoughtful discussion on his website, Flutterby, about developing Interprocess Standards as a way of bootstrapping new languages (and other ramifications, but that's the one that is germane here).
This can be achieved using command cgo.
In essence
'If the import of "C" is immediately preceded by a comment, that comment, called the preamble, is used as a header when compiling the C parts of the package. For example:'
source:https://golang.org/cmd/cgo/
// #include <stdio.h>
// #include <errno.h>
import "C"