Description
What version of Go are you using (go version
)?
$ go version go version go1.15.3 windows/amd64
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env set GO111MODULE= set GOARCH=amd64 set GOBIN= set GOCACHE=C:\Users\samue\AppData\Local\go-build set GOENV=C:\Users\samue\AppData\Roaming\go\env set GOEXE=.exe set GOFLAGS= set GOHOSTARCH=amd64 set GOHOSTOS=windows set GOINSECURE= set GOMODCACHE=C:\Users\samue\go\gopath\pkg\mod set GONOPROXY= set GONOSUMDB= set GOOS=windows set GOPATH=C:\Users\samue\go\gopath set GOPRIVATE= set GOPROXY=https://proxy.golang.org,direct set GOROOT=C:\Users\samue\sdk\go1.15.3 set GOSUMDB=sum.golang.org set GOTMPDIR= set GOTOOLDIR=C:\Users\samue\sdk\go1.15.3\pkg\tool\windows_amd64 set GCCGO=gccgo set AR=ar set CC=gcc set CXX=g++ set CGO_ENABLED=1 set GOMOD= set CGO_CFLAGS=-g -O2 set CGO_CPPFLAGS= set CGO_CXXFLAGS=-g -O2 set CGO_FFLAGS=-g -O2 set CGO_LDFLAGS=-g -O2 set PKG_CONFIG=pkg-config set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\samue\AppData\Local\Temp\go-build596418074=/tmp/go-build -gno-record-gcc-switches
What did you do?
I am trying to compile my code to a shared library (specifically a dll on Windows; there is no issue on Linux).
Here is what I found to be a minimally reproducible example.
package main
import "C"
import "fmt"
import "github.com/karalabe/hid"
//export HelloWorld
func HelloWorld() *C.char {
var err error
fmt.Print("Hello world!")
devices := hid.Enumerate(0, 0)
for _ = range devices {
fmt.Printf("Found a device\n")
}
if nil != err {
return C.CString(err.Error())
} else {
return C.CString("Hello World!")
}
}
func main() {
HelloWorld()
}
I then compile the shared library using the following commands:
SET CGO_ENABLED=1
go build -buildmode=c-shared -o main.dll main.go
I get the following files:
main.dll
main.h
Here is the header file:
/* Code generated by cmd/cgo; DO NOT EDIT. */
/* package command-line-arguments */
#line 1 "cgo-builtin-export-prolog"
#include <stddef.h> /* for ptrdiff_t below */
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
#endif
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
#endif
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern char* HelloWorld();
#ifdef __cplusplus
}
#endif
The function is declared in the header, as expected. However,
rundll32.exe main.dll,HelloWorld
Expectations / things that would show it works
I would expect this error box not to show up basically. If I remove the dependency to the HID library it works, the call is made. I believe this might be a bug with Go and not the library because it works on Linux and I get an otherwise valid header file, and basically no relevant warning while compiling.
I would have expected that if no entry was to be created, I would get a compilation error / warning / advisory. I do get a warning while compiling but it's from the included library. The same warning occurs while building the app (which works). I am including it here just in case, but I do not believe it has anything to do with the issue; it's a fairly standard warning when using strncpy
# github.com/karalabe/hid
In file included from C:\Users\samue\go\gopath\src\github.com\karalabe\hid\hid_enabled.go:40:
C:\Users\samue\go\gopath\src\github.com\karalabe\hid/hidapi/windows/hid.c: In function 'hid_enumerate':
C:\Users\samue\go\gopath\src\github.com\karalabe\hid/hidapi/windows/hid.c:431:5: warning: 'strncpy' specified bound depends on the length of the source argument [-Wstringop-overflow=]
strncpy(cur_dev->path, str, len+1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\samue\go\gopath\src\github.com\karalabe\hid/hidapi/windows/hid.c:429:11: note: length computed here
len = strlen(str);
^~~~~~~~~~~