Is it practical to send these changes upstream to SWIG?
> I just make a patch for swig go support windows port, swig go really useful
> for bind c++ to go, please see the attachments for patch.
Thanks! Can you also provide a patch which updates the documentation in
Doc/Manual/Go.html?
It would also be helpful to e-mail the patch to
swig-...@lists.sourceforge.net to see what the SWIG developers think
of it.
Thanks.
Ian
> I add -windows and -exename to args for windows dynimport and dynexport, for
> example, Example/go/callback make process as follow:
> ../../../preinst-swig -go -c++ -windows -exename runme.exe example.i
> 8g -I . example.go
> dlltool -d runme.exe.def -l runme.a
> g++ -g -c example.cxx example_wrap.cxx
> g++ -shared example.o example_wrap.o runme.a -o example.dll
> -Wl,--out-imp,libexample.a
> 8c -I ${GOROOT}/pkg/${GOOS}_${GOARCH} example_gc.c
> gopack grc example.a example.8 example_gc.8
> 8g -I . runme.go
> 8l -o runme.exe -L . runme.8
> ./runme.exe
>
> --
> Wei guangjing
>
> Index: Examples/go/callback/Makefile.win
> ===================================================================
> --- Examples/go/callback/Makefile.win (revision 0)
> +++ Examples/go/callback/Makefile.win (revision 0)
> @@ -0,0 +1,26 @@
> +TOP = ../..
> +SWIG = $(TOP)/../preinst-swig
> +CXXSRCS = example.cxx
> +TARGET = example
> +INTERFACE = example.i
> +SWIGOPT = -windows -exename runme.exe
> +LIBS=-L. -lrunme
> +
> +all:: go
> +
> +go::
> + ../../../preinst-swig -go -c++ ${SWIGOPT} ${INTERFACE}
> + 8g -I . example.go
> + dlltool -d runme.exe.def -l runme.a
> + g++ -g -c example.cxx example_wrap.cxx
> + g++ -shared example.o example_wrap.o runme.a -o example.dll -Wl,--out-imp,libexample.a
> + 8c -I ${GOROOT}/pkg/${GOOS}_${GOARCH} example_gc.c
> + gopack grc example.a example.8 example_gc.8
> + 8g -I . runme.go
> + 8l -o runme.exe -L . runme.8
> +
> +clean::
> + $(MAKE) -f $(TOP)/Makefile go_clean
> +
> +check: all
> + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
> Index: Source/Modules/go.cxx
> ===================================================================
> --- Source/Modules/go.cxx (revision 12454)
> +++ Source/Modules/go.cxx (working copy)
> @@ -27,6 +27,9 @@
> String *soname;
> // Size in bits of the C type "long".
> int long_type_size;
> + // Flag for Windows
> + bool windows_flag;
> + String *exename;
>
> /* Output files */
> File *f_c_begin;
> @@ -46,6 +49,7 @@
> File *f_gc_runtime;
> File *f_gc_header;
> File *f_gc_wrappers;
> + File *f_gc_dynexports;
>
> // True if we imported a module.
> bool saw_import;
> @@ -86,6 +90,8 @@
> go_prefix(NULL),
> soname(NULL),
> long_type_size(32),
> + windows_flag(false),
> + exename(NULL),
> f_c_begin(NULL),
> f_go_begin(NULL),
> f_gc_begin(NULL),
> @@ -101,6 +107,7 @@
> f_gc_runtime(NULL),
> f_gc_header(NULL),
> f_gc_wrappers(NULL),
> + f_gc_dynexports(NULL),
> saw_import(false),
> imported_package(NULL),
> interfaces(NULL),
> @@ -138,6 +145,9 @@
> } else if (strcmp(argv[i], "-gccgo") == 0) {
> Swig_mark_arg(i);
> gccgo_flag = true;
> + } else if (strcmp(argv[i], "-windows") == 0) {
> + Swig_mark_arg(i);
> + windows_flag = true;
> } else if (strcmp(argv[i], "-go-prefix") == 0) {
> if (argv[i + 1]) {
> go_prefix = NewString(argv[i + 1]);
> @@ -156,6 +166,15 @@
> } else {
> Swig_arg_error();
> }
> + } else if (strcmp(argv[i], "-exename") == 0) {
> + if (argv[i + 1]) {
> + exename = NewString(argv[i + 1]);
> + Swig_mark_arg(i);
> + Swig_mark_arg(i + 1);
> + i++;
> + } else {
> + Swig_arg_error();
> + }
> } else if (strcmp(argv[i], "-longsize") == 0) {
> if (argv[i + 1]) {
> long_type_size = atoi(argv[i + 1]);
> @@ -240,7 +259,10 @@
> }
> if (!soname) {
> soname = Copy(package);
> - Append(soname, ".so");
> + if (windows_flag)
> + Append(soname, ".dll");
> + else
> + Append(soname, ".so");
> }
>
> // Get filenames.
> @@ -256,6 +278,12 @@
> gc_filename = NewString("");
> Printf(gc_filename, "%s%s_gc.c", SWIG_output_directory(), module);
> }
> +
> + String *gc_dynexport_filename = NULL;
> + if (windows_flag && exename) {
> + gc_dynexport_filename = NewString("");
> + Printf(gc_dynexport_filename, "%s.def", exename);
> + }
>
> // Open files.
>
> @@ -282,6 +310,14 @@
> FileErrorDisplay(go_filename);
> SWIG_exit(EXIT_FAILURE);
> }
> +
> + if (windows_flag && exename) {
> + f_gc_dynexports = NewFile(gc_dynexport_filename, "w", SWIG_output_files());
> + if (!f_gc_dynexports) {
> + FileErrorDisplay(gc_dynexport_filename);
> + SWIG_exit(EXIT_FAILURE);
> + }
> + }
>
> if (!gccgo_flag) {
> f_gc_begin = NewFile(gc_filename, "w", SWIG_output_files());
> @@ -341,9 +377,16 @@
> if (!gccgo_flag) {
> Swig_banner(f_gc_begin);
> Printf(f_gc_begin, "\n/* This file should be compiled with 6c/8c. */\n");
> - Printf(f_gc_begin, "#pragma dynimport _ _ \"%s\"\n", soname);
> + if (!windows_flag)
> + Printf(f_gc_begin, "#pragma dynimport _ _ \"%s\"\n", soname);
> }
>
> + if (windows_flag && exename) {
> + Printf(f_gc_dynexports, "LIBRARY %s\n", exename);
> + Printf(f_gc_dynexports, "EXPORTS\n");
> + Printf(f_gc_dynexports, "_cgo_allocate\n_cgo_panic\ncrosscall2\n");
> + }
> +
> // Output module initialization code.
>
> Printf(f_go_begin, "\npackage %s\n\n", package);
> @@ -998,9 +1041,13 @@
> int gcFunctionWrapper(Node *n, String *name, String *go_name, String *overname, String *wname, ParmList *parms, SwigType *result, bool is_static, bool needs_wrapper) {
> Wrapper *f = NewWrapper();
>
> - Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"\"\n", NULL);
> + if (windows_flag)
> + Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"", soname, "\"\n", NULL);
> + else
> + Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"\"\n", NULL);
> Printv(f->def, "extern void (*", wname, ")(void*);\n", NULL);
> - Printv(f->def, "static void (*x", wname, ")(void*) = ", wname, ";\n", NULL);
> + if (!windows_flag)
> + Printv(f->def, "static void (*x", wname, ")(void*) = ", wname, ";\n", NULL);
> Printv(f->def, "\n", NULL);
> Printv(f->def, "void\n", NULL);
>
> @@ -1056,7 +1103,10 @@
> Delete(parm_size);
>
> Printv(f->code, "{\n", NULL);
> - Printv(f->code, "\truntime\xc2\xb7" "cgocall(x", wname, ", &p);\n", NULL);
> + if (windows_flag)
> + Printv(f->code, "\truntime\xc2\xb7" "cgocall(", wname, ", &p);\n", NULL);
> + else
> + Printv(f->code, "\truntime\xc2\xb7" "cgocall(x", wname, ", &p);\n", NULL);
> Printv(f->code, "}\n", NULL);
> Printv(f->code, "\n", NULL);
>
> @@ -2737,6 +2787,8 @@
> Printv(f_c_directors, " a.p = go_val;\n", NULL);
> Printv(f_c_directors, " crosscall2(", wname, ", &a, (int) sizeof a);\n", NULL);
>
> + if (windows_flag && exename)
> + Printf(f_gc_dynexports, "%s\n", wname);
> Printv(f_gc_wrappers, "#pragma dynexport ", wname, " ", wname, "\n", NULL);
> Printv(f_gc_wrappers, "extern void \xc2\xb7", go_name, "();\n", NULL);
> Printv(f_gc_wrappers, "void\n", NULL);
> @@ -3463,6 +3515,8 @@
> }
>
> // The C wrapper code which calls the Go function.
> + if (windows_flag && exename)
> + Printf(f_gc_dynexports, "%s\n", callback_wname);
> Printv(f_gc_wrappers, "#pragma dynexport ", callback_wname, " ", callback_wname, "\n", NULL);
> Printv(f_gc_wrappers, "extern void \xc2\xb7", callback_name, "();\n", NULL);
> Printv(f_gc_wrappers, "void\n", NULL);
> @@ -4743,4 +4797,6 @@
> -go-prefix <p> - Like gccgo -fgo-prefix option\n\
> -soname <name> - Set shared library holding C/C++ code to <name>\n\
> -longsize <s> - Set size of C/C++ long type--32 or 64 bits\n\
> + -windows - Windows\n\
> + -exename - exe file name, for Windows\n\
> \n";
Wei guangjing <vcc...@gmail.com> writes:Thanks! Can you also provide a patch which updates the documentation in
> I just make a patch for swig go support windows port, swig go really useful
> for bind c++ to go, please see the attachments for patch.
Doc/Manual/Go.html?
It would also be helpful to e-mail the patch to
swig-...@lists.sourceforge.net to see what the SWIG developers think
of it.
Hi Wei,
Do you think there is a way to use the dll created without hard coding
the executable name? I would like to build a generic package that uses
SWIG to wrap a C++ library.
> I can't get variables defined in C
> but I can invoke functions defined in C.
SWIG will give you getter and setter functions. You can not directly
refer to variables defined in C++ from Go code.
> //println(test.MyVar) //when uncomment this line show up "main.go:7:
> undefined: test.MyVar" error.
test.GetMyVar()
Ian