Skip to content

Import constants from C++ headers for Go without 'cgo'

License

Notifications You must be signed in to change notification settings

nyaosorg/go-importconst

Repository files navigation

go-importconst

When you wanted to refer to a C constant in Go-sources, you had to use "cgo" or copy it by hand. As a result, you have to require a C compiler as a build requirement.

With go-importconst , the C compiler is only needed when using go generate, not when go build.

The go-importconst is called by go generate to generate, compile and execute C source files that generate "Go source files that define the desired constants".

from const.go :

package dos

//go:generate go run github.com/nyaosorg/go-importconst
//	<windows.h>
//	RESOURCE_CONNECTED
//	RESOURCE_CONTEXT
//	RESOURCE_GLOBALNET
//	RESOURCE_REMEMBERED
//	RESOURCETYPE_ANY
//	RESOURCETYPE_DISK
//	RESOURCETYPE_PRINT
//	RESOURCEDISPLAYTYPE_NETWORK
//	RESOURCEDISPLAYTYPE_SERVER
//	RESOURCEUSAGE_CONNECTABLE
//	RESOURCEUSAGE_CONTAINER
//	RESOURCEUSAGE_ATTACHED
//	RESOURCEUSAGE_ALL
//	ERROR_NO_MORE_ITEMS
//	CONNECT_UPDATE_PROFILE
//	S_OK

go generate creates the go-source (zconst.go) like below

$ go get github.com/nyaosorg/go-importconst
go: downloading github.com/nyaosorg/go-importconst v0.2.0
go: added github.com/nyaosorg/go-importconst v0.2.0
$ go generate
C:\Users\hymkor\scoop\apps\gcc\current\bin\gcc.exe zconst.cpp
.\a.exe zconst.go
rm .\a.exe
C:\go\bin\go.exe fmt zconst.go
rm zconst.cpp
package dos

// Code generated by go-importconst DO NOT EDIT.
const RESOURCE_CONNECTED = 1
const RESOURCE_CONTEXT = 5
const RESOURCE_GLOBALNET = 2
const RESOURCE_REMEMBERED = 3
const RESOURCETYPE_ANY = 0
const RESOURCETYPE_DISK = 1
const RESOURCETYPE_PRINT = 2
const RESOURCEDISPLAYTYPE_NETWORK = 6
const RESOURCEDISPLAYTYPE_SERVER = 2
const RESOURCEUSAGE_CONNECTABLE = 1
const RESOURCEUSAGE_CONTAINER = 2
const RESOURCEUSAGE_ATTACHED = 16
const RESOURCEUSAGE_ALL = 19
const ERROR_NO_MORE_ITEMS = 259
const CONNECT_UPDATE_PROFILE = 1
const S_OK = 0

Mechanism

  1. Creates the C++ source file like below
  2. Compile it with gcc
  3. Run the executable and redirect stdout to zconst.go
#include <cstdio>
#include <windows.h>

void p(FILE *w,const char *name,const char *s){
	fprintf(w,"const %s = \"%s\"\n",name,s);
}
void p(FILE *w,const char *name,int n){
	fprintf(w,"const %s = %d\n",name,n);
}
void p(FILE *w,const char *name,long n){
	fprintf(w,"const %s = %ld\n",name,n);
}
void p(FILE *w,const char *name,unsigned long n){
	fprintf(w,"const %s = %lu\n",name,n);
}
void p(FILE *w,const char *name,double n){
	fprintf(w,"const %s = %lf\n",name,n);
}

int main(int argc,char **argv)
{
    if ( argc < 2 ){ return 1; }
    FILE *w=fopen(argv[1],"wb");
    if ( w == NULL ){ return 2; }
    fprintf(w,"package dos\n\n");
    fprintf(w,"// Code generated by go-importconst DO NOT EDIT.\n");
    p(w,"RESOURCE_CONNECTED",RESOURCE_CONNECTED);
    p(w,"RESOURCE_CONTEXT",RESOURCE_CONTEXT);
    p(w,"RESOURCE_GLOBALNET",RESOURCE_GLOBALNET);
    p(w,"RESOURCE_REMEMBERED",RESOURCE_REMEMBERED);
    p(w,"RESOURCETYPE_ANY",RESOURCETYPE_ANY);
    p(w,"RESOURCETYPE_DISK",RESOURCETYPE_DISK);
    p(w,"RESOURCETYPE_PRINT",RESOURCETYPE_PRINT);
    p(w,"RESOURCEDISPLAYTYPE_NETWORK",RESOURCEDISPLAYTYPE_NETWORK);
    p(w,"RESOURCEDISPLAYTYPE_SERVER",RESOURCEDISPLAYTYPE_SERVER);
    p(w,"RESOURCEUSAGE_CONNECTABLE",RESOURCEUSAGE_CONNECTABLE);
    p(w,"RESOURCEUSAGE_CONTAINER",RESOURCEUSAGE_CONTAINER);
    p(w,"RESOURCEUSAGE_ATTACHED",RESOURCEUSAGE_ATTACHED);
    p(w,"RESOURCEUSAGE_ALL",RESOURCEUSAGE_ALL);
    p(w,"ERROR_NO_MORE_ITEMS",ERROR_NO_MORE_ITEMS);
    p(w,"CONNECT_UPDATE_PROFILE",CONNECT_UPDATE_PROFILE);
    p(w,"S_OK",S_OK);
    fclose(w);
    return 0;
}

Install

If you want to use with go:generate go-importconst instead of go:generate go run github.com/nyaosorg/go-importconst, you can install as below

Download the binary package from Releases and extract the executable.

for scoop-installer

scoop install https://raw.githubusercontent.com/nyaosorg/go-importconst/master/go-importconst.json

or

scoop bucket add nyaosorg https://github.com/nyaosorg/scoop-bucket
scoop install go-importconst

Options

  • -c
    • clean output
  • -cc string
    • c compiler command (default "gcc")
  • -csrc string
    • c-source filename used temporally (default "zconst.cpp")
  • -d
    • debug flag
  • -lowercamel
    • AAA_BBB_CCC to aaaBbbCcc
  • -nofmt
    • do not execute go fmt (for debug)
  • -o string
    • go-source-filename to output constants (default "zconst.go")
  • -prefix string
    • append string to symbol as prefix
  • -uppercamel
    • AAA_BBB_CCC to AaaBbbCcc

Author

@hymkor

License

You can use, copy and modify under the MIT License.