Cgo can't find standard libraries like <iostream> - c++

I'm trying to include C++ code in my Go code, but isn't recognized.
I first thought that it considers it as C code and try (and fail) to compile as such, but removing the include line actually gives me c++ error troubleshooting like this
error: ‘cout’ is not a member of ‘std’
The code compiles correctly with g++.
I have tried to add the -lstdc++ LDLFLAG, and add the path to the lib in CXXFLAG but it doesn't change a thing.
I have made some other tests (and all fail) but this is the smallest one.
This is the c++ files
test.cpp
#include "test.hpp"
int test()
{
std::cout << "Hello, World! ";
return 0;
}
test.hpp
#include <iostream>
int test() ;
And this is my go file
//#cgo CXXFLAGS: -I/usr/lib/
//#cgo LDFLAGS: -L/usr/lib/ -lstdc++
//#include "test.hpp"
import "C"
func main() {
C.test()
}
I compile using go build but I have also tried to use env CGO_ENABLED CGO_CXXFLAGS="-std=c++11" go build (the env part is fish specific) and it returns the same error.
It's supposed to compile correctly, but instead I have iostream: No such file or directory.
EDIT :
I tried to add CFLAGS: -x c++ as suggested in the comments, the compiler searches at the right place, but I get another error invalid conversion from ‘void*’ to ‘_cgo_96e70225d9dd_Cfunc_test(void*)::<unnamed struct>*’ [-fpermissive] and I don't know if it's related to this new flafg

cgo makes it very easy to wrap C with Go, but C++ is a bit different. You have to extern "C" the functions that you want to make a function-name in C++ have 'C' linkage, otherwise the linker won't see the function. So, the actual problem is in the C++ header file. If you can't change the C++ code because it's a library, you may have to write wrappers (example).
This will compile:
.
├── test.cpp
├── test.go
└── test.hpp
test.hpp
#ifdef __cplusplus
extern "C" {
#endif
int test();
#ifdef __cplusplus
}
#endif
test.cpp
#include <iostream>
#include "test.hpp"
int test() {
std::cout << "Hello, World! ";
return 0;
}
test.go
package main
// #cgo CXXFLAGS: -I/usr/lib/
// #cgo LDFLAGS: -L/usr/lib/ -lstdc++
// #include "test.hpp"
import "C"
func main() {
C.test()
}
Put the files in the same folder,
run go build
Hello, World!

Related

SWIG wrapper of C++ library for Python - submodules

I'm trying to wrap a C++ library into a Python3 interface using SWIG, and there is a problem I can't quite fix. This library has several namespaces, and I would like to make them modules of the library when wrapped in Python. Assume the following minimal example:
lib_class.hpp lib_class.cpp
lib_ops.hpp lib_ops.cpp
io_ops.hpp io_ops.cpp
The files lib_class define a very small class:
lib_class.hpp
#pragma once
namespace lib {
class dummy {
private:
int a;
public:
dummy();
dummy(int t_a);
~dummy();
void asdf();
};
}
lib_class.cpp
#include "lib_class.hpp"
namespace lib {
dummy::dummy() {}
dummy::dummy(int t_a) : a(t_a) {}
dummy::~dummy() {}
void dummy::asdf() { a = 3; }
}
The files lib_ops.hpp and lib_ops.cpp define a only one function:
lib_ops.hpp:
#pragma once
namespace lib {
void lib_operation();
}
lib_ops.cpp:
#include "lib_ops.hpp"
#include <iostream>
using namespace std;
namespace lib {
void lib_operation() {
cout << "LIBRARY TOP LEVEL" << endl;
}
}
and, finally, the files io_ops.hpp io_ops.cppdefine another function, this time within the namespacelib::io```:
io_ops.hpp
#pragma once
#include "lib_class.hpp"
namespace lib {
namespace io {
void io_operation(dummy& a);
}
}
io_ops.cpp
#include "io_ops.hpp"
#include <iostream>
using namespace std;
namespace lib {
namespace io {
void io_operation(dummy& a) {
cout << "LIBRARY SUBMODULE" << endl;
a.asdf();
}
}
}
I would like to wrap these files into a Python interface so that I can:
import lib
d = lib.dummy(10)
lib.ioop.io_operation(d)
lib.lib_operation()
In other words, I would like the organization of the Python wrapper to be:
lib.dummy # class
lib.lib_operation # function
lib.ioop # submodule
lib.ioop.io_operation # function within submodule
I've written the following *.i files:
lib.i:
%module lib
%import ioop.i
%{
#include "lib_ops.hpp"
#include "lib_class.hpp"
%}
%include "lib_ops.hpp"
%include "lib_class.hpp"
ioop.i:
%module ioop
%{
#include "io_ops.hpp"
using namespace lib;
%}
%include "io_ops.hpp"
This compiles without errors with:
g++ -c -fPIC io_ops.cpp
g++ -c -fPIC lib_ops.cpp
g++ -c -fPIC lib_class.cpp
swig -c++ -python -py3 lib.i
swig -c++ -python -py3 ioop.i
g++ -fPIC -c lib_wrap.cxx -I /usr/include/python3.6
g++ -fPIC -c ioop_wrap.cxx -I /usr/include/python3.6
g++ -fPIC -shared -o _lib.so lib_wrap.o lib_ops.o lib_class.o
g++ -fPIC -shared -o _ioop.so ioop_wrap.o io_ops.o lib_class.o
however, the python script above gives the following error:
Traceback (most recent call last):
File "test.py3", line 5, in <module>
lib.ioop.io_operation(d)
File "/home/lluis/Desktop/example.i/ioop.py", line 66, in io_operation
return _ioop.io_operation(a)
TypeError: in method 'io_operation', argument 1 of type 'dummy &'
Although I managed to "insert" the namespace lib::io into the "main" module lib as a submodule ioop, it looks as though it didn't know anything about the class lib::dummy.
Is it possible to do this? If so, how can I do it?
Thanks to all of you for your time (and sorry for such a lengthy post).
As #Flexo pointed out in one of the comments, the file ioops.i needs an %import. The correct contents of the file are:
%module ioop
%import lib.i
%{
#include "io_ops.hpp"
using namespace lib;
%}
%include "io_ops.hpp"

How can I define my class in a different source file to my main function?

Trivial as it ought to be, I just cannot figure out how to separate my source code into different files.
My code compiles and executes just fine when it is written as a single source file:
#include <iostream>
using namespace std;
class Greeter{
public:
void greet();
};
void Greeter::greet(){
cout << "Hello World!";
}
int main(){
Greeter greeter;
greeter.greet();
return 0;
}
But try as I might, separating the code into separate source files:
Greeter.h
#include <iostream>
using namespace std;
class Greeter{
public:
Greeter();
void greet();
};
Greeter.cxx
#include <iostream>
#include "Greeter.h"
using namespace std;
void Greeter::greet(){
cout << "Hello World!";
}
main.cxx
#include <iostream>
#include "Greeter.h"
using namespace std;
int main(){
Greeter greeter;
greeter.greet();
return 0;
}
always results in a compilation error:
main.cxx:(.text+0x16): undefined reference to `Greeter::Greeter()'
It is unclear whether the comments solved your problem. In separating your source into a header and multiple sources, your primary problem evidenced by the error is that you include an incomplete constructor for class Greeter in Greeter.h. Specifically, you fail to include "an empty parameter list" to complete the constructor, e.g.
Greeter() {}; /* default construct */
See cppreference - Default constructors
The next issue you should avoid is including using namespace std; in the header file. See “using namespace” in c++ headers. Instead, simply make your call to cout, std::cout and eliminate the need to include the namespace altogether.
Next, while iostream has proper header guards, you only need to include it in Greeter.cpp (that is the only source making use of an iostream function). You should also include header guards in your Greeter.h to prevent multiple inclusions during compilation. Simply create a #define and check whether or not that is already defined within the header, e.g.
greeter.h
#ifndef my_class_greeter_h
#define my_class_greeter_h 1
class Greeter {
public:
Greeter() {}; /* default construct */
void greet();
};
#endif
Now every file that includes greeter.h will avoid including it again if my_class_greeter_h is already defined.
greeter.cpp
Your source file with your class function definition is the only source that relies on an iostream call, and is the only file that requires #include <iostream>, e.g.
#include <iostream>
#include "greeter.h"
void Greeter::greet(){
std::cout << "Hello World!\n";
}
main.cpp
You main.cpp source file need only include your header containing the class definition, e.g.
#include "greeter.h"
int main (void) {
Greeter greeter; /* instantiate greeter */
greeter.greet(); /* call greet() */
return 0;
}
Both Sources Must Be Compiled
Compiling the separate source files requires that both main.cpp and greeter.cpp be compiled (either compiling greeter.cpp to object or by simply including both .cpp files in your compile string).
Compiling With gcc/clang
$ g++ -Wall -Wextra -pedantic -std=c++11 -Ofast -o main main.cpp greeter.cpp
Compiling With VS (cl.exe)
> cl /nologo /W3 /Ox /EHsc /Femain /TP main.cpp greeter.cpp
(do not accept code until it compiles without warning)
Example Use/Output
In either case, the output is as expected:
$ ./main
Hello World!
Look things over and let me know if you have further questions.

How to properly include Header and Implementation Files?

I am a novice programmer in c++, and I am currently getting a compiling error
Undefined symbols for architecture x86_64
Supposedly this originates from how the header files and implementation files are included/coded.
Below is some code that generates the compiling error I am receiving
Main
//Main.cpp
#include <iostream>
#include <string>
#include "Animal.hpp"
using namespace std;
int main(){
Animal myPet;
myPet.shout();
return 0;
}
Header
//Animal.hpp
#ifndef H_Animal
#define H_Animal
using namespace std;
#include <string>
class Animal{
public:
Animal();
void shout();
private:
string roar;
};
#endif
Implementation
//Animal.cpp
#include "Animal.hpp"
#include <string>
Animal::Animal(){
roar = "...";
}
void Animal::shout(){
roar = "ROAR";
cout << roar;
}
This code generates my compiling issue. How would this issue be resolved?
Thanks for your time
EDIT
Undefined symbols for architecture x86_64:
"Animal::shout()", referenced from:
_main in test-5f7f84.o
"Animal::Animal()", referenced from:
_main in test-5f7f84.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
maybe you might want to see an alternative set of your 3 files, where things are a little more "sorted", you know, where things are put at places where they "really" belong to.
So here's the "new" header file ..
//Animal.hpp
#ifndef H_Animal
#define H_Animal
#include <string> // suffices
// Interface.
class Animal {
std::string roar; // private
public:
Animal();
void shout();
};
#endif
then the source file ..
//Animal.cpp
#include "Animal.hpp"
#include <iostream> // suffices
// Constructor.
Animal::Animal()
:
roar("...") // data member initializer
{}
// Member function.
void Animal::shout() {
roar = "ROAR";
std::cout << roar;
}
and the main program ..
//Main.cpp
#include "Animal.hpp"
int main(){
Animal thePet;
thePet.shout(); // outputs: `ROAR'
}
plus a little GNU makefile ..
all: default run
default: Animal.cpp Main.cpp
g++ -o Main.exe Animal.cpp Main.cpp
run:
./Main.exe
clean:
$(RM) *.o *.exe
Kick-off things typing just "make" in your cmd-line. Did you like it? --
Regards, M.
I can only find one error in your code and your compiler should have told you that one.
In Animal.cpp, you are using std::cout but you're not #includeing <iostream>. You #include it in Main.cpp but it is not needed there.
If you (really) want to refer to std::cout as cout in Animal.cpp, you also have to add a using namespace std directive in that file.
The using directive in the header file (Animal.hpp) is evil. Get rid of it and type std::string instead. Putting using directives into headers litters the namespaces of all files that use it.
I also don't understand your intentions with the roar member. What is the point of assigning "..." to it in the constructor and re-assigning "ROAR" to it every time shout is called? Couldn't you do without that variable and simply have
void
Animal::shout()
{
std::cout << "ROAR\n";
}
? I have added a newline because you'd probably want one.
The main issue I was having with this coding project was solved by #JamesMoore.
"#Nicholas Hayden Okay if you have three files, test.cpp(which has main), animal.cpp, and animal.hpp. The command should be g++ animal.cpp test.cpp. You need to compile all source files."
I am currently not using an IDE. So, when I was calling the compiler to compile my main.cpp - It was an issue of compiling the implementation file.
g++ test.cpp
needed to become
g++ test.cpp animal.cpp
This would call the compiler to compile everything the program needed.

How to use header files?

I wanted to learn using header files. and I got an error. here is my code:
printmyname.h:
void printMyName();
printmyname.cpp:
#include "printmyname.h"
void printMyName() {
cout << "omer";
}
try.cpp (main file):
#include <iostream>
#include "printmyname.h"
using namespace std;
int main() {
printMyName();
return 0;
}
Here is the error:
undefined reference to `printMyName()`
What's is the problem?
Undefine reference has nothing to do with your header file in this case. It means the linker cannot find the implementation of printMyName which is in printmyname.cpp. If you are using g++, you should try:
g++ try.cpp printmyname.cpp -o yourBinaryName
If you are using a makefile, you should add dependency(printmyname.cpp) correctly for try.cpp.
Edit:
As #zmo suggest in his comment:
you can also do it through a two times compilation (more suitable with Makefiles):
g++ -c printmyname.cpp
g++ try.cpp printmyname.o -o yourBinaryName
If you are using Windows, you need to add the printmyname.cpp to your project too.
Consider adding an include guard to your header
#ifndef PRINTMYNAME_INCLUDED
#define PRINTMYNAME_INCLUDED
void printMyName();
#endif
You will also need to move the #include <iostream> and using namespace std; from the try.cpp to the printmyname.cpp file.
You need to add code/definition in printMyName.cpp inside printMyName.h only.
void printMyName();
{
cout << "omer";
}

How can I use the flex lexical scanner generator as part of my program?

How can I use a scanner I've written using Flex as part of a program I'm designing? Specifically, within a c++ class as a method of the class, and from a separate file with just a main method to perform testing.
I don't wish to use the %option c++, but will compile with g++.
To answer the problem of how to test the scanner from a separate file's main I attempted with the following code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
extern "C" {
extern int yylex();
}
extern FILE* yyin;
int main(int argc, char *argv[]) {
if (argc > 1)
yyin = fopen(argv[1], "r");
yylex();
return 0;
}
I compile like so:
flex mylexer.l++
g++ lex.mylexer.C myDriver.C -o myLexer
I get:
undefined reference to yyin
undefined reference to yylex
What is the correct way to compile/setup the driver file?
Thank you for reading and contributing anything!
The simplist example I have is:
mylex.l
%option noyywrap
%%
: return ':';
%%
main.cpp
#include <stdio.h>
#include <iostream>
extern "C"
{
extern int yylex(void);
extern FILE* yyin;
}
int main()
{
yyin = fopen("plop", "r");
std::cout << yylex() << "\n";
}
Then to build:
> flex -o mylex.c mylex.l
> gcc -c mylex.c
> g++ -c main.cpp
> g++ main.o mylex.o
Notice the gcc to compile the mylex.c
If you compile mylex.c with g++ it will be compiled as C++ (not C) and your extern "C" declarations in main would be wrong. Thus you need to compile the mylex.c and main.cpp with different compilers then link them together in separate steps.
Version 2:
Alternatively you can compile the flex code as C++ and remove the extern "C" from main.
main.cpp
#include <stdio.h>
#include <iostream>
extern int yylex(void);
extern FILE* yyin;
int main()
{
yyin = fopen("plop", "r");
std::cout << yylex() << "\n";
}
Now Build like this:
> flex -o mylex.c mylex.l
> g++ -c mylex.c
> g++ -c main.cpp
> g++ main.o mylex.o
Notice this time I used g++ to compile mylex.c (which you could call mylex.cpp now).
Now that you are using the same compiler it can be a one liner:
> flex -o mylex.c mylex.l
> g++ mylex.c main.cpp
You have to link the flex library with your programm, that is, you have to add -lfl to your g++compiler invocation.
flex mylexer.l++
g++ lex.mylexer.C myDriver.C -o myLexer -lfl
You need to include the file generated by flex on your g++ command line -- both yyin and yylex are defined there. If lex.mylexer.C is supposed to be that file, its possible that you're getting a flex error you're ignoring, or otherwise not running flex properly to generate the file -- check it to make sure that it actually contains the flex output and isn't an empty file.
Check out boost Spirit