I'm trying to use swig to interface with c++, and I'm having problems using a std::string&
parameter. This is on Fedora 19 with golang 1.1-2, swig 2.0.10-1, and gcc 4.8.1-1.
I don't know C++. I do know C, and had hoped to wing it. At any rate, _swig_wrap_pinput
ends up with a null pointer.
What am I overlooking?
Here's my test case:
st.i
%module st
%{
#include <string>
extern void pinput(std::string& pstring);
%}
%include <std_string.i>
#include <string>
void pinput(std::string& pstring);
st.cxx
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
void pinput(std::string& pstring) {
std::cout<<pstring;
}
stmain.go
package main
import (
"st"
)
func main() {
myLit:="This is a test."
st.Pinput(&myLit)
}
Makefile
SWIGOBJS = st_gc.c st_wrap.cxx st.go
all: st.so st.a
$(SWIGOBJS): st.i
swig -go -c++ -intgosize 64 st.i
st.o: st.cxx
g++ -c -fpic -g -o st.o st.cxx
st_wrap.o: st_wrap.cxx
g++ -c -fpic -g -o st_wrap.o st_wrap.cxx
st.so: st_wrap.o st.o
g++ -shared st_wrap.o st.o -o st.so
st_gc.6: st_gc.c
/usr/lib64/golang/pkg/tool/linux_amd64/6c -I /usr/lib64/golang/pkg/linux_amd64 st_gc.c
st.6: st.go
/usr/lib64/golang/pkg/tool/linux_amd64/6g st.go
st.a: st.6 st_gc.6
go tool pack grc st.a st.6 st_gc.6
test: stmain
stmain: stmain.6
/usr/lib64/golang/pkg/tool/linux_amd64/6l stmain.6
stmain.6: stmain.go
/usr/lib64/golang/pkg/tool/linux_amd64/6g stmain.go
Since the question was originally asked both Go and SWIG have updated. I will post a solution that worked for me (Go 1.3.3, SWIG 3.0.2). As you can see, the difference to the original post is minimal.
The most recommended approach is to use go build. It knows nowadays to look for *.swig and *.swigcxx files, and runs both SWIG and GCC/G++ automatically based on the information found in the swig interface file.
stmain.go
package main
import (
"st" // This will be created by SWIG
)
func main() {
myLit:="This is a test."
st.Pinput(myLit)
}
st/st.h
ifndef ST_H
#define ST_H
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
void pinput(const std::string& pstring);
#endif
st/st.cpp
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
void pinput(const std::string& pstring) {
std::cout << pstring;
std::cout << std::endl; // Without endl the stdout doesn't get flushed for me -> no output
}
st/st.go
package st
// Without any Go file in the directory the go build will fail
st/st.swigcxx
%module st
%include "std_string.i"
%include "st.h"
%{
extern void pinput(const std::string& pstring);
%}
void pinput(const std::string& pstring);
To build & run
// Quick'n'dirty version
# go build stmain.go
# ./stmain
This is a test.
#
Alternatively you can build the same sources manually with 6g/c/l/swig/gotool, for example my simplified version:
Makefile:
all:
make -C st
/usr/local/go/pkg/tool/linux_amd64/6g -I st stmain.go
/usr/local/go/pkg/tool/linux_amd64/6l -o stmain -extldflags -lstdc++ -L st stmain.6
clean:
rm -f *.6 6.out
make clean -C st
test: stmain
st/Makefile:
all: clean
swig -go -intgosize 64 -c++ -soname st.so st.swigcxx
g++ -c st.cpp -o st.o
g++ -c st_wrap.cxx -o st_wrap.o
/usr/local/go/pkg/tool/linux_amd64/6c -I /usr/local/go/pkg/linux_amd64/ -D _64BIT st_gc.c
/usr/local/go/pkg/tool/linux_amd64/6g st.go
go tool pack grc st.a st.6 st_gc.6 st.o st_wrap.o
clean:
rm -f *.6
rm -f *.a
rm -f *.so
rm -f *.cxx
rm -f *.c
rm -f *.o