字符串参数

huangapple go评论88阅读模式
英文:

String parameters

问题

我正在尝试使用swig与c++进行接口交互,但是在使用std::string&参数时遇到了问题。这是在Fedora 19上使用golang 1.1-2,swig 2.0.10-1和gcc 4.8.1-1时发生的。

我不懂C++。我知道C,并希望能够应付。无论如何,_swig_wrap_pinput最终得到了一个空指针。

我忽视了什么?

这是我的测试案例:

st.i

%module st
%{
#include <string>
extern void pinput(std::string&amp; pstring);
%}
%include <std_string.i>
#include <string>
void pinput(std::string&amp; pstring);

st.cxx

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>

void pinput(std::string&amp; 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
英文:

I'm trying to use swig to interface with c++, and I'm having problems using a std::string&amp; 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 &lt;string&gt;
extern void pinput(std::string&amp; pstring);
%}
%include &lt;std_string.i&gt;
#include &lt;string&gt;
void pinput(std::string&amp; pstring);

st.cxx

#include &lt;stddef.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;

void pinput(std::string&amp; pstring) {
  std::cout&lt;&lt;pstring;
}

stmain.go

package main
import (
       &quot;st&quot;
)

func main() {
     myLit:=&quot;This is a test.&quot;
     st.Pinput(&amp;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

答案1

得分: 2

由于问题最初是用Go和SWIG提出的,我将发布一个对我有效的解决方案(Go 1.3.3,SWIG 3.0.2)。如您所见,与原帖的区别很小。

最推荐的方法是使用go build。它现在知道查找*.swig和*.swigcxx文件,并根据swig接口文件中找到的信息自动运行SWIG和GCC/G++。

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.
#

或者,您可以使用6g/c/l/swig/gotool手动构建相同的源代码,例如我的简化版本:

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
英文:

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 (
       &quot;st&quot; // This will be created by SWIG
)

func main() {
     myLit:=&quot;This is a test.&quot;
     st.Pinput(myLit)
}

st/st.h

ifndef ST_H
#define ST_H

#include &lt;stddef.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;

void pinput(const std::string&amp; pstring);

#endif

st/st.cpp

#include &lt;stddef.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;

void pinput(const std::string&amp; pstring) {
  std::cout &lt;&lt; pstring;
  std::cout &lt;&lt; std::endl; // Without endl the stdout doesn&#39;t get flushed for me -&gt; 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 &quot;std_string.i&quot;
%include &quot;st.h&quot;
%{
extern void pinput(const std::string&amp; pstring);
%}

void pinput(const std::string&amp; pstring);

To build & run

// Quick&#39;n&#39;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

huangapple
  • 本文由 发表于 2013年7月20日 02:29:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/17753105.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定