C++ and Go 1.2

2,074 views
Skip to first unread message

Dorival Pedroso

unread,
Aug 26, 2013, 12:37:35 AM8/26/13
to golan...@googlegroups.com
Hi, I've heard Go 1.2 (CGO) supports C++ now... Is there any example/doc on how to link a C++ library the way? Cheers. Dorival

Ian Lance Taylor

unread,
Aug 26, 2013, 1:34:30 AM8/26/13
to Dorival Pedroso, golang-nuts
The cgo program doesn't really support C++. It will work for straight
functions in C++, but not for methods.

You can use SWIG to interface with C++ code.

Ian

Stephen Gutekanst

unread,
Aug 26, 2013, 1:34:44 AM8/26/13
to golan...@googlegroups.com
I too am interested in what sort of things CGO can do when interacting with C++.

(For those curious, revision is here: https://code.google.com/p/go/source/detail?r=24596e5bca7d)

What level of interaction can be done with C++ classes and OO model?

Stephen

Stephen Gutekanst

unread,
Aug 26, 2013, 1:53:20 AM8/26/13
to golan...@googlegroups.com, Dorival Pedroso
It seems me and Ian mailed at nearly the same time.

Ian's response answers my questions fully.

Stephen

Dorival Pedroso

unread,
Aug 26, 2013, 2:32:42 AM8/26/13
to golan...@googlegroups.com, Dorival Pedroso
thanks a lot for the reply.

the wrapping code i'm creating involves only straight functions in C++

nonetheless, i'm struggling with linkage problems (small code attached)

cheers.
d
connectmpi.cpp
connectmpi.h
main.go
mpi.go

Sebastien Binet

unread,
Aug 26, 2013, 2:35:27 AM8/26/13
to Dorival Pedroso, golang-nuts
Dorival,

connectmpi.h needs to read:

#ifndef CONNECTMPI_H
#define CONNECTMPI_H

#ifdef __cplusplus
extern "C" {
#endif

void startmpi(int debug);
void stopmpi(int debug);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif // CONNECTMPI_H


-s
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
Message has been deleted
Message has been deleted

Dorival Pedroso

unread,
Aug 26, 2013, 3:06:20 AM8/26/13
to golan...@googlegroups.com
here it goes a very small example using boost...
if i learn how to link this i'll probably be able to fix the mpi example as well
i'm compiling and running with:
g++ `go env GOGCCFLAGS` -shared -o libexcpp.so cpplib.cpp
go build main.go


the problem with the other mpi test is:
    mpic++ `go env GOGCCFLAGS` -shared -o libconnectmpi.so connectmpi.cpp
    go build main.go
/usr/bin/ld: $WORK/mpi/_obj/connectmpi.cpp.o: undefined reference to symbol '_ZN3MPI8Datatype4FreeEv'
/usr/lib/libmpi_cxx.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status


many thanks in advance!
cheers

cpplib.cpp
golib.go
main.go

Sebastien Binet

unread,
Aug 26, 2013, 3:37:05 AM8/26/13
to Dorival Pedroso, golang-nuts
Dorival,


On Mon, Aug 26, 2013 at 8:39 AM, Dorival Pedroso <dorival...@gmail.com> wrote:
thanks a lot; but after changed as suggested i still have the same problems

i'm compiling with:
mpic++ `go env GOGCCFLAGS` -shared -o libconnectmpi.so connectmpi.cpp

and building with:
go build main.go

the errors are:
/usr/bin/ld: $WORK/mpi/_obj/connectmpi.cpp.o: undefined reference to symbol '_ZN3MPI8Datatype4FreeEv'
/usr/lib/libmpi_cxx.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

I'll try another example that doesn't involve MPI to see how it goes

the following worked for me:

$ cat mpi.go
 package mpi

/*
#cgo CFLAGS: -O3 -I. -I/usr/include/mpi
#cgo LDFLAGS: -L/usr/lib/openmpi -lmpi -lmpi_cxx -lstdc++
#include "connectmpi.h"
*/
import "C"

// Start initialises MPI
func Start(debug bool) {
if debug {
C.startmpi(1)
} else {
C.startmpi(0)
}
}

// Stop finalises MPI
func Stop(debug bool) {
if debug {
C.stopmpi(1)
} else {
C.stopmpi(0)
}
}

$ cat 
$ go get .
$ go run main.go
startmpi: hi from 0. debug = 1
stopmpi: goodbye from 0. debug = 1

that's the whole point of the CL mentionned earlier in this thread: don't require a Makefile for compiling cxx files which expose a C-API and have those file blend seamlessly into the "go get" machinery.

-s


cheers.
d
--
Dr Dorival Pedroso MSc PhD Brisbane Australia +61 0420411142 http://www.cpmech.com Lecturer School of Civil Engineering The University of Queensland


Dorival Pedroso

unread,
Aug 26, 2013, 4:01:24 AM8/26/13
to golan...@googlegroups.com, Dorival Pedroso
thanks a lot Sebastien.

the method fixed my problem as well and the idea is quite interesting: avoiding an intermediary .so file...

just another quick question: is it possible to include something like:
`mpic++ -showme:link`
into the .go file?

ps: i'll post the fix with the boost test soon as well
cheers
d

Sebastien Binet

unread,
Aug 26, 2013, 4:09:30 AM8/26/13
to Dorival Pedroso, golang-nuts
On Mon, Aug 26, 2013 at 10:01 AM, Dorival Pedroso <dorival...@gmail.com> wrote:
thanks a lot Sebastien.

the method fixed my problem as well and the idea is quite interesting: avoiding an intermediary .so file...

just another quick question: is it possible to include something like:
`mpic++ -showme:link`
into the .go file?
nope.
although, if you can somehow translate this information into a pkg-config file, then you're golden.
(as go-get can be instructed to use pkg-config files to automatically configure the build)

-s

Gerard

unread,
Aug 26, 2013, 6:47:52 AM8/26/13
to golan...@googlegroups.com, Dorival Pedroso
I bet the answer is yes, but is this documented somewhere?

mobiled...@gmail.com

unread,
Aug 26, 2013, 4:27:29 PM8/26/13
to golan...@googlegroups.com


On Sunday, August 25, 2013 9:37:35 PM UTC-7, Dorival Pedroso wrote:

Dorival Pedroso

unread,
Aug 26, 2013, 9:55:52 PM8/26/13
to golan...@googlegroups.com
Thanks for the help, everyone!

For reference, I'm posting an example using boost:

files structure:
$GOPATH/src
     /excpp
          cpplib.cpp
          cpplib.h
          golib.go
     /use_excpp
          main.go

cpplib.cpp
#include <string>
#include <iostream>
#include <boost/algorithm/searching/boyer_moore.hpp>
extern "C" {
void runalgo() {
    namespace ba = boost::algorithm;
    std::string haystack("ABACAB is it everywhere!");
    std::string needle1 ("ACAB");
    std::string needle2 ("not ABA");
    if (ba::boyer_moore_search(haystack.begin(), haystack.end(), needle1.begin(), needle1.end()) != haystack.end ()) {
        std::cout << "Found '" << needle1 << "'  in '" << haystack << "' (boyer-moore 1)" << std::endl;
    } else {
        std::cout << "Did NOT find '" << needle1 << "'  in '" << haystack << "' (boyer-moore 1)" << std::endl;
    }
}
} // extern "C"

cpplib.h
#ifndef CPPLIB_H 
  #define CPPLIB_H 
  #ifdef __cplusplus 
  extern "C" { 
  #endif 

  void runalgo();

  #ifdef __cplusplus 
  }
  #endif 
#endif

golib.go
package excpp

/*
#cgo LDFLAGS: -lstdc++
#include "cpplib.h"
*/
import "C"

// GoRunAlgo
func GoRunAlgo() {
    C.runalgo()
}

main.go
package main

import (
    "excpp"
)

func main() {
    excpp.GoRunAlgo()
}

to run only (and not install):
  go build main.go

with:
  go install 
from the excpp directory,  we get a static library named excpp.a in $GOPATH/pkg/...

nm excpp.a
nm: __.GOSYMDEF: File format not recognized
nm: __.PKGDEF: File format not recognized
nm: _go_.6: File format not recognized
nm: _cgo_import.6: File format not recognized
nm: _cgo_defun.6: File format not recognized

_all.o:
                 U __assert_fail
0000000000000000 T _cgo_cb939bbdcaaf_Cfunc_runalgo
                 U __cxa_atexit
                 U __dso_handle
0000000000000000 V DW.ref.__gxx_personality_v0
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 t _GLOBAL__sub_I_cpplib.cpp
                 U __gxx_personality_v0
0000000000000000 r .LC0
0000000000000000 r .LC1
0000000000000074 r .LC10
0000000000000018 r .LC2
0000000000000022 r .LC3
000000000000002c r .LC4
0000000000000045 r .LC5
000000000000004a r .LC6
0000000000000052 r .LC7
000000000000005a r .LC8
0000000000000062 r .LC9
                 U memset
                 w __pthread_key_create
0000000000000010 T runalgo
                 U _Unwind_Resume
                 U _ZdlPv
0000000000000000 W _ZN5boost9algorithm18boyer_moore_searchIN9__gnu_cxx17__normal_iteratorIPcSsEES5_EET0_S6_S6_T_S7_
                 U _ZNKSt5ctypeIcE13_M_widen_initEv
                 U _ZNSo3putEc
                 U _ZNSo5flushEv
                 U _ZNSs12_M_leak_hardEv
                 U _ZNSs4_Rep10_M_destroyERKSaIcE
                 U _ZNSs4_Rep10_M_disposeERKSaIcE
                 U _ZNSs4_Rep20_S_empty_rep_storageE
                 U _ZNSsC1EPKcRKSaIcE
                 U _ZNSt8ios_base4InitC1Ev
                 U _ZNSt8ios_base4InitD1Ev
                 U _ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate
                 U _Znwm
                 U _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
                 U _ZSt16__throw_bad_castv
                 U _ZSt17__throw_bad_allocv
                 U _ZSt4cout
0000000000000000 b _ZStL8__ioinit
0000000000000000 t _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc.part.2
0000000000000000 r _ZZN5boost9algorithm11boyer_mooreIN9__gnu_cxx17__normal_iteratorIPcSsEENS0_6detail9BM_traitsIS5_EEE17compute_bm_prefixINS3_IS4_St6vectorIcSaIcEEEESB_IlSaIlEEEEvT_SH_RT0_E19__PRETTY_FUNCTION__
00000000000001c0 r _ZZN5boost9algorithm11boyer_mooreIN9__gnu_cxx17__normal_iteratorIPcSsEENS0_6detail9BM_traitsIS5_EEE17compute_bm_prefixIS5_St6vectorIlSaIlEEEEvT_SE_RT0_E19__PRETTY_FUNCTION__


So, apparently all boost functions are (statically) in excpp.a?

Cheers,
Dorival

Bonly H

unread,
Dec 1, 2013, 8:57:24 AM12/1/13
to golan...@googlegroups.com
I want to know about support of c++ in go 1.2  version too..

在 2013年8月27日星期二UTC+8上午9时55分52秒,Dorival Pedroso写道:

Andrew Gerrand

unread,
Dec 1, 2013, 10:10:10 PM12/1/13
to Bonly H, golang-nuts

On 2 December 2013 00:57, Bonly H <h.b...@gmail.com> wrote:
I want to know about support of c++ in go 1.2  version too..

Reply all
Reply to author
Forward
0 new messages