Qt5.4 How can I create an app based in plugins? - c++

I have an app in QT 5.4 but when I need include a new functionality, I need recompile all the app, this take a time, I need know how create or modified my app to use plugins created by me.

A plugin-based architecture requires binary compatible and stable interfaces. Once you have these, a full-project recompilation should take about as much time as recompiling a single plugin.
Most likely, you have interdependencies in your code that preclude maintaining binary compatibility anyway - if you didn't, your changes would be localized enough so that a recompilation would only touch a couple of files.
What you're trying to do is come up with a solution to the wrong problem. Fix the structure of your code, and your recompilation times will drop. No need for plugins.

There are many alternatives; a popular one consists of using shared libraries implementing a well-defined API.
For example. Imagine this is the API you want to open for customization:
// pluggin_api.hpp
// This file defines the pluggin interface.
#pragma once
extern "C" { // avoid name mangling
const char* pluggin_name();
void foo(int x);
void bar(int y);
}
Then your users (or yourself) will implement different variations of this API, for example:
// pluggin_1.cpp
#include "pluggin_api.hpp"
#include <iostream>
const char* pluggin_name() {
return "Pluggin 1";
}
void foo(int x) {
std::cout << "2 * x = " << 2 * x << std::endl;
}
void bar(int y) {
std::cout << " 3 * y = " << 3 * y << std::endl;
}
and
// pluggin_2.cpp
#include "pluggin_api.hpp"
#include <iostream>
const char* pluggin_name() {
return "Pluggin 2";
}
void foo(int x) {
std::cout << "20 * x = " << 20 * x << std::endl;
}
void bar(int y) {
std::cout << " 30 * y = " << 30 * y << std::endl;
}
These .cpp files are compiled as shared libraries; under Linux it looks like this:
$ g++ -shared -fPIC -o pluggin_1.so pluggin_1.cpp
$ g++ -shared -fPIC -o pluggin_2.so pluggin_2.cpp
Finally, the main application can call the different pluggins by name:
// main.cpp
#include <iostream>
#include <dlfcn.h> // POSIX --- will work on Linux and OS X, but
// you'll need an equivalent library for Windows
void execute_pluggin(const char* name) {
// declare the signature of each function in the pluggin -- you
// could do this in the header file instead (or another auxiliary
// file)
using pluggin_name_signature = const char*(*)();
using foo_signature = void(*)(int);
using bar_signature = void(*)(int);
// open the shared library
void* handle = dlopen(name, RTLD_LOCAL | RTLD_LAZY);
// extract the functions
auto fun_pluggin_name = reinterpret_cast<pluggin_name_signature>(dlsym(handle, "pluggin_name"));
auto fun_foo = reinterpret_cast<foo_signature>(dlsym(handle, "foo"));
auto fun_bar = reinterpret_cast<bar_signature>(dlsym(handle, "bar"));
// call them
std::cout << "Calling Pluggin: " << fun_pluggin_name() << std::endl;
fun_foo(2);
fun_bar(3);
// close the shared library
dlclose(handle);
}
int main(int argc, char *argv[]) {
for(int k = 1; k < argc; ++k) {
execute_pluggin(argv[k]);
}
}
Compile and link with the dl library:
$ g++ -o main main.cpp -std=c++14 -ldl
and run (notice you need the ./ before the name; this has to do with library naming conventions and search paths):
$ ./main ./pluggin_1.so ./pluggin_2.so
Calling Pluggin: Pluggin 1
2 * x = 4
3 * y = 9
Calling Pluggin: Pluggin 2
20 * x = 40
30 * y = 90
There are so many details that I left out (most importantly error management). I recommend you read the book API Design for C++ to find alternative ideas (such as using an scripting language, using inheritance, using templates, and a mix of them).
I like the shared library method because then I can use the pluggins in other applications (for example: I can use Python's ctypes library, or Matlab's loadlibrary). I can also write the pluggin in, say, Fortran, and then wrap it in an interface compatible with the API.
Finally: notice that this has absolutely nothing to do with QT (though QT may provide a platform-independent shared library loader; I don't know). This is just a common manner in which people provide hooks for customization.

The Qt Documentation provides a 'How To' on creating plugins to extend a Qt based application using Qt's own mechanisms. See http://doc.qt.io/qt-5/plugins-howto.html.
It talks about a high-level API and a low-level API. You are interested in the low-level API.

Related

How do I use the pthreads in a ROS C++ Node

I am trying to use pthread library inside the ros Node, I am including it as #include <pthread>. When I run catkin_make I get the error below. I created a simple thread as std::thread m1(move, 1);
thread: No such file or directory
#include <pthread>
^~~~~~~~~
The signature of the move function is void move(short axis_no, short direction = 0) and I instantiated the thread as
std::thread m1(move, 1);
m1.join();
I tried to add the pthread library in my CmakeLists.txt as follows
add_compile_options(-std=c++11 -pthread) and
target_link_libraries(pthread). Is there a way I can use the pthread library inside the ros Node?
Thank you.
pthread is a C library available on some platforms and if you want to use the pthread_* functions you need to #include <pthread.h>.
Since C++11 there is an abstraction layer on top of the native threading libraries which is available if you instead #include <thread>.
You can then use std::thread - but you will still need to link with -pthread.
Instead of hardcoding -pthread, you can let CMake find and add the appropriate library:
find_package(Threads REQUIRED)
target_link_libraries(your_app PRIVATE Threads::Threads)
In your program, the move function needs two arguments (the function signature is void(*)(short, short) even if you have a default value for direction).
#include <thread>
#include <iostream>
void move(short axis_no, short direction = 0) {
std::cout << axis_no << ' ' << direction << '\n';
}
int main() {
auto th = std::thread(move, 1, 2); // needs 2 arguments
th.join();
}
If you want, you can create an overload to only have to supply one argument, but in that case you also need to help the compiler to select the correct overload.
#include <thread>
#include <iostream>
void move(short axis_no, short direction) { // no default value here
std::cout << axis_no << ' ' << direction << '\n';
}
void move(short axis_no) { // proxy function
move(axis_no, 0); // where 0 is default
}
int main() {
using one = void(*)(short);
using two = void(*)(short, short);
// use one of the above type aliases to select the proper overload:
auto th = std::thread(static_cast<one>(move), 1);
th.join();
}

Normal or anormal behaviour of dynamic libraries with C++ static objects

I'm developing a framework heavily based on plugin implemented as dynamic libraries (on Linux, .so files). All was working fine until I made a plugin depending on another plugin and, as the plugins were implemented as a static instance of a dedicated class, I found the following problem that I reduced to a the following small set of code:
Source of liba.so is here:
class A {
public:
A(void) {
cerr << "A(" << this << ")\n";
}
};
A x;
int y;
Source of libb.so is below and depends on liba.so:
extern int y;
class B {
public:
B(void) {
cerr << "B(" << this << ")\n";
y = 0;
}
};
B x;
int z;
Notice that both classes provides the same symbol x with different type. This situation may happen when one library evolves and unexpectedly uses a new symbol that conflicts with an unknown library or code using it.
Writing a small program using libb.so:
extern int z;
int main(void) {
z = 0;
cerr << "main\n";
return 0;
}
Executing it gives:
casse#ares ~/tmp/tso $ ./main
A(0x7f689dfc605c)
B(0x7f689dfc605c)
main
Both constructors of x in liba.so and libb.so are executed and display the "this" address and they display the same address! Is this normal behavior? It seems strange that the constructors of static objects are confused by two storage with the same name. Is it a bug? GCC or Linux?
Thanks to whoever can help me.

Is there any way to transform strings into compileable/runnable code?

For example, suppose we have a string like:
string x = "for(int i = 0; i < 10; i++){cout << \"Hello World!\n\";}"
What is the simplest way to complete the following function definition:
void do_code(string x); /* given x that's valid c++ code, executes that code as if it were written inside of the function body */
The standard C++ libraries do not contain a C++ parser/compiler. This means that your only choice is to either find and link a C++ compiler library or to simply output your string as a file and launch the C++ compiler with a system call.
The first thing, linking to a C++ compiler, would actually be quite doable in something like Visual Studio for example, that does indeed have DLL libraries for compiling C++ and spitting out a new DLL that you could link at runtime.
The second thing, is pretty much what any IDE does. It saves your text-editor stuff into a C++ file, compile it by system-executing the compiler and run the output.
That said, there are many languages with build-in interpreter that would be more suitable for runtime code interpretation.
Not directly as you're asking for C++ to be simultaneously compiled and interpreted.
But there is LLVM, which is a compiler framework and API. That would allow you to take in this case a string containing valid C++, invoke the LLVM infrastructure and then afterwards use a LLVM-based just in time compiler as described at length here. Keep in mind you must also support the C++ library. You should also have some mechanism to map variables into your interpreted C++ and take data back out.
A big but worthy undertaking, seems like someone might have done something like this already, and maybe Cling is just that.
Use the Dynamic Linking Loader (POSIX only)
This has been tested in Linux and OSX.
#include<fstream>
#include<string>
#include<cstdlib>
#include<dlfcn.h>
void do_code( std::string x ) {
{ std::ofstream s("temp.cc");
s << "#include<iostream>\nextern \"C\" void f(){" << x << '}'; }
std::system( "g++ temp.cc -shared -fPIC -otemp.o" );
auto h = dlopen( "./temp.o", RTLD_LAZY );
reinterpret_cast< void(*)() >( dlsym( h, "f" ) )();
dlclose( h );
}
int main() {
std::string x = "for(int i = 0; i < 10; i++){std::cout << \"Hello World!\\n\";}";
do_code( x );
}
Try it online! You'll need to compile with the -ldl parameter to link libdl.a. Don't copy-paste this into production code as this has no error checking.
Works for me:
system("echo \"#include <iostream> \nint main() { for(int i = 0; i < 10; i++){std::cout << i << std::endl;} }\" >temp.cc; g++ -o temp temp.cc && ./temp");

Is it possible to create a function dynamically, during runtime in C++?

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;
}

How to use C++ in Go

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"