integer division in Go called from C - go

I am able to perform integer division in go by this program :
package main
import "fmt"
func main() {
a := 10
b := 5
fmt.Println(a/b)
}
Then I made a program in go that has functions for +, -, * and /.
and I made a program in C that calls each of these functions and performs arithmetic operations.
Except division, the code works fine.
The go file with the functions is : (calc.go)
package main
func Add(a, b int) int {
return a + b
}
func Sub(a, b int) int {
return a - b
}
func Mul(a, b int) int {
return a * b
}
func Div(a, b int) int {
return a / b
}
And the C program that calls these functions is : (calcc.c)
#include <stdio.h>
extern int go_add(int, int) __asm__ ("main.Add");
extern int go_sub(int, int) __asm__ ("main.Sub");
extern int go_mul(int, int) __asm__ ("main.Mul");
extern int go_div(int, int) __asm__ ("main.Div");
int menu()
{
int op;
printf("\n1 add");
printf("\n2 sub");
printf("\n3 mul");
printf("\n4 div");
printf("\nEnter your choice : ");
scanf("%d", &op);
return op;
}
int main() {
int op, ch, result, a, b;
do{
op= menu();
printf("First number : ");
scanf("%d", &a);
printf("Second number : ");
scanf("%d", &b);
switch(op)
{
case 1:
result = go_add(a, b);
printf("Result : %d" , result);
break;
case 2:
result = go_sub(a, b);
printf("Result : %d" , result);
break;
case 3:
result = go_mul(a, b);
printf("Result : %d" , result);
break;
case 4:
result = go_div(a, b);
printf("Result : %d" , result);
break;
default:
printf("Invalid choice ! ");
}
printf("\nAnother operation? (1 if yes) : ");
scanf("%d", &ch);
} while(ch==1);
printf("\nThank you!");
}
I compiled on the terminal using the commands :
gccgo -c calc.go
and
gcc calc.o calcc.c -o main
And got this error :
undefined reference to `__go_runtime_error'
collect2: error: ld returned 1 exit status
How should I fix this?

You need to link using gccgo and not with normal gcc. Normal gcc doesn't know that it ought to link against the go runtime (libgo).
Depending on your configuration, you might also need to specify where the runtime library can be found. For example by embedding it statically or by making it available in the LD_LIBRARY_PATH environment variable.
Example:
gccgo -static-libgo calc.o calcc.o -o main
For more information, check Setting up and using gccgo.

I believe your method of using __asm__ is gccgo specific (I've never seen it before).
The standard way to export Go functions to C is via an "//export name" comment in the Go code.
Further, standard Go<->C via cgo requires that C code is linked into Go and Go's main runs and not the other way around. This is so that the Go runtime is fully running. Otherwise goroutines, the garbage collector, etc would not be running. Of course Go's main could just be a simple call to a C pseudo-main function that does all the work and calls back into Go only as needed.
Given these points a small example of what you tried using standard cgo and fully go build-able is this:
calc.go:
package main
// /* could be in a declared in a header file instead */
// extern void pseudo_main(void);
import "C"
//export Add
func Add(a, b int) int {
return a + b
}
// … etc …
//export Div
func Div(a, b int) int {
return a / b
}
// Main needs to be Go so that the go runtime
// gets started so you can use goroutines, the
// garbage collector, etc,etc.
//
// It can just be a trivial call into a C main like
// function.
func main() {
C.pseudo_main()
}
and calc.c:
#include <stdio.h>
#include "_cgo_export.h" // file auto-generated by cgo from Go's "//export func" comments
// passing argc, argv, envp like arguments
// if desired is left as an excersise :)
void pseudo_main(void) {
int x, y, z;
printf("Hello from C\n");
x = 42;
y = 6;
z = Add(x, y);
printf("%d + %d = %d\n", x, y, z);
z = Div(x, y);
printf("%d / %d = %d\n", x, y, z);
}
building and running (on a Unix like host):
% go build -o calc
% ./calc
Note: normally you wouldn't use -o, you'd let the tool pick the name based on package or directory name. I've used -o here to list exact and repeatable commands without specifying what directory the files are in. Further note, for Microsoft Windows it would be different. Also, if you're interested in what goes on behind the scenes with cgo, try go build -x.
output:
Hello from C
42 + 6 = 48
42 / 6 = 7
gist.github.com
See also: The Go Blog: C? Go? Cgo!

Related

implicit declaration of function ‘_beginthread’ when call go library from c code

i want to call go method in c code
os is windows10
i use Cygwin64 Terminal
main.go
package main
import "C"
func main() {}
//export number_add_mod
func number_add_mod(a, b, mod C.int) C.int {
return (a + b) % mod
}
_test_main.c
#include "number.h"
#include <stdio.h>
int main() {
int a = 10;
int b = 5;
int c = 12;
int x = number_add_mod(a, b, c);
printf("(%d+%d)%%%d = %d\n", a, b, c, x);
return 0;
}
when i run
go build -buildmode=c-archive -o number.a
report error
# runtime/cgo
gcc_libinit_windows.c: in function‘x_cgo_sys_thread_create’:
gcc_libinit_windows.c:57:12: error:implicit declaration of function ‘_beginthread’; did you mean ‘OpenThread’? [-Werror=implicit-function-declaration]
thandle = _beginthread(func, 0, arg);
^~~~~~~~~~~~
OpenThread
cc1:
go: failed to remove work dir: GetFileInformationByHandle D:\cygwin64new\tmp\go-build109746670\NUL: Incorrect function.
make: *** [Makefile:5:default]
i install tdm-gcc solved problem
http://tdm-gcc.tdragon.net/download/

Runtime error with cgo and certain string slices

I have stripped back a problem I have come across whilst wrapping some C code to work with golang using swig but the problem doesn't rest with swig.
I can pass in a basic string slice but as soon as I construct the slice with anything other than basic strings, I get a panic: runtime error: cgo argument has Go pointer to Go pointer.
go version go1.8.5 linux/amd64
This is the sample code and its output
package main
import (
"fmt"
"reflect"
"unsafe"
)
/*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct { char *p; int n; } _gostring_;
typedef struct { void* array; int len; int cap; } _goslice_;
void prtText(char * const *txt, int len)
{
int i = 0;
for ( i=0; i<len; i++ ) {
printf("Text %d is: %s\n", i, txt[i]);
}
}
void _wrap_printText(_goslice_ _swig_go_0) {
_gostring_ *p;
char **arg1 = (char **)calloc(_swig_go_0.len, sizeof(char*));
if (arg1) {
for (int i=0; i<_swig_go_0.len; i++) {
p = &(((_gostring_*)_swig_go_0.array)[i]);
arg1[i] = calloc(1,(p->n)+1);
strncpy(arg1[i], p->p, p->n);
}
}
int arg2 = _swig_go_0.len;
prtText((char *const *)arg1,arg2);
}
*/
import "C"
func PrintText(arg1 []string) {
C._wrap_printText(*(*C._goslice_)(unsafe.Pointer(&arg1)))
}
func main() {
s := []string{}
s = append(s, "blah")
s = append(s, "hello")
s = append(s, "again")
ns := []string{}
ns = append(ns, "ns: "+s[0])
ns = append(ns, "ns: "+s[1])
ns = append(ns, "ns: "+s[2])
fmt.Println("type s:", reflect.TypeOf(s))
fmt.Println("type ns:", reflect.TypeOf(ns))
fmt.Println("s:", s)
fmt.Println("ns:", ns)
PrintText(s)
PrintText(ns)
}
go build -i -x -gcflags '-N -l' main.go
./main
type s: []string
type ns: []string
s: [blah hello again]
ns: [ns: blah ns: hello ns: again]
Text 0 is: blah
Text 1 is: hello
Text 2 is: again
panic: runtime error: cgo argument has Go pointer to Go pointer
As you can see, the first string slice works fine but as soon as I do anything other than basic strings, it fails. I've tried making new strings first before appending them to the slice but the problem remains.
What am I doing wrong?
You're basically passing the raw Go pointers.
Instead, you should build C arrays yourself.
As a general rule, seeing unsafe pretty much anywhere should make you suspicious. It is rarely the right way around issues with cgo.
Using the helpers from Passing array of string as parameter from go to C function and using them in your code:
package main
import (
"fmt"
"reflect"
)
/*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void prtText(char * const *txt, int len)
{
int i = 0;
for ( i=0; i<len; i++ ) {
printf("Text %d is: %s\n", i, txt[i]);
}
}
static char**makeCharArray(int size) {
return calloc(sizeof(char*), size);
}
static void setArrayString(char **a, char *s, int n) {
a[n] = s;
}
static void freeCharArray(char **a, int size) {
int i;
for (i = 0; i < size; i++)
free(a[i]);
free(a);
}
*/
import "C"
func main() {
s := []string{}
s = append(s, "blah")
s = append(s, "hello")
s = append(s, "again")
ns := []string{}
ns = append(ns, "ns: "+s[0])
ns = append(ns, "ns: "+s[1])
ns = append(ns, "ns: "+s[2])
fmt.Println("type s:", reflect.TypeOf(s))
fmt.Println("type ns:", reflect.TypeOf(ns))
fmt.Println("s:", s)
fmt.Println("ns:", ns)
sargs := C.makeCharArray(C.int(len(s)))
defer C.freeCharArray(sargs, C.int(len(s)))
for i, p := range s {
C.setArrayString(sargs, C.CString(p), C.int(i))
}
nsargs := C.makeCharArray(C.int(len(ns)))
defer C.freeCharArray(nsargs, C.int(len(ns)))
for i, p := range ns {
C.setArrayString(nsargs, C.CString(p), C.int(i))
}
C.prtText(sargs, C.int(len(s)))
C.prtText(nsargs, C.int(len(ns)))
}
The output is now as expected:
$ ./main
type s: []string
type ns: []string
s: [blah hello again]
ns: [ns: blah ns: hello ns: again]
Text 0 is: blah
Text 1 is: hello
Text 2 is: again
Text 0 is: ns: blah
Text 1 is: ns: hello
Text 2 is: ns: again

golang: how to simulate union type efficiently

As known, go has no union type, and should only be simulated via interface.
I try two methods to simulate the union, but the result is far from good as C.
package main
import (
"fmt"
"time"
)
type U interface {
i32() int32
i16() int16
}
type i32 int32
func (u i32) i32() int32 {
return int32(u)
}
func (u i32) i16() int16 {
return int16(u)
}
type i16 int16
func (u i16) i32() int32 {
return int32(u)
}
func (u i16) i16() int16 {
return int16(u)
}
func test() (total int64) {
type A struct {
t int32
u interface{}
}
a := [...]A{{1, int32(100)}, {2, int16(3)}}
for i := 0; i < 5000000000; i++ {
p := &a[i%2]
switch p.t {
case 1:
total += int64(p.u.(int32))
case 2:
total += int64(p.u.(int16))
}
}
return
}
func test2() (total int64) {
type A struct {
t int32
u U
}
a := [...]A{{1, i32(100)}, {2, i16(3)}}
for i := 0; i < 5000000000; i++ {
p := &a[i%2]
switch p.t {
case 1:
total += int64(p.u.i32())
case 2:
total += int64(p.u.i16())
}
}
return
}
type testfn func() int64
func run(f testfn) {
ts := time.Now()
total := f()
te := time.Now()
fmt.Println(total)
fmt.Println(te.Sub(ts))
}
func main() {
run(test)
run(test2)
}
result:
257500000000
1m23.508223094s
257500000000
34.95081661s
The method way is better, and the type-cast way cost more CPU time.
The C version:
#include <stdio.h>
struct A {
int t;
union {
int i;
short v;
} u;
};
long test()
{
struct A a[2];
a[0].t = 1;
a[0].u.i = 100;
a[1].t = 2;
a[1].u.v = 3;
long total = 0;
long i;
for (i = 0; i < 5000000000; i++) {
struct A* p = &a[i % 2];
switch(p->t) {
case 1:
total += p->u.i;
break;
case 2:
total += p->u.v;
break;
}
}
return total;
}
int main()
{
long total = test();
printf("%ld\n", total);
}
result:
257500000000
real 0m5.620s
user 0m5.620s
sys 0m0.000s
The union type is useful for many applications, e.g. network protocol may contains variant concrete type.
So maybe the access of union data may become the bottleneck of the application.
Anybody could help? Thanks.
You can use arrays to represent a single int32 as two int16s and then assemble them with shifts as Rob Pike recommends:
func test3() (total int64) {
type A struct {
t int32
u [2]int16
}
a := [...]A{
{1, [2]int16{100, 0}},
{2, [2]int16{3, 0}},
}
for i := 0; i < N; i++ {
p := &a[i%2]
switch p.t {
case 1:
total += int64(p.u[0]<<0 | p.u[1]<<8)
case 2:
total += int64(p.u[0])
}
}
return
}
With the original Go compiler it runs about 2 times slower than the C version, and with gccgo (-O3) it runs about as fast as C.
Be warned though that this approach assumes little-endian ints. You'll need to switch the order of shifts for big-endian architecture.
Also, if you need to decode structures from a byte slice, you should really be using encoding/binary. This library is created to translate between byte sequences and other types.
I bet myself to make it much closer to C variant, and here's what I got:
(full code)
https://play.golang.org/p/3FJTI6xSsd8
thing is that we going through all struct's fields and redirect them to buffer's storage (which has compile-time len refereed from template struct, for sake of memory salvation and universality)
result:
func test() (total int64) {
type A struct {
t int32
u struct {
// embedded buffer of union
FooSize
// mark all types inside as pointer types
i *int32 // long
v *int16 //short
}
}
var a [2]A
// initialize them
Union(&a[0].u)
Union(&a[1].u)
a[0].t = 1
*a[0].u.i = 100
a[1].t = 2
*a[1].u.v = 3
for c := 0; c < 5000000000; c++ {
p := &a[c%2]
switch p.t {
case 1:
total += int64(*p.u.i)
case 2:
total += int64(*p.u.v)
}
}
return
}
// your bench:
257500000000
8.111239763s
// native bench (8,18800064s):
BenchmarkUnion 1 8188000640 ns/op 80 B/op 1 allocs/op
Ran it on $5 digitalocean droplet.
Implementation is cursed and may be not compatible with future versions of Go (current is 1.13), but usage (as behavior) is C-like, also supports any type (you can replace integers with structs as well)
The union may contains numeric types and octet string, so I try to use byte slice as the value container and use unsafe.Pointer to access it according to the concrete type.
func test3() (total int64) {
type A struct {
t int32
u []byte
}
a := [...]A{{1, make([]byte, 8)}, {2, make([]byte, 8)}}
*(*int32)(unsafe.Pointer(&a[0].u)) = 100
*(*int16)(unsafe.Pointer(&a[1].u)) = 3
for i := 0; i < 5000000000; i++ {
p := &a[i%2]
switch p.t {
case 1:
total += int64(*(*int32)(unsafe.Pointer(&p.u)))
case 2:
total += int64(*(*int16)(unsafe.Pointer(&p.u)))
}
}
return
}
result:
$ go run union.go
257500000000
12.844752701s
$ go run -compiler gccgo -gccgoflags -O3 union.go
257500000000
6.640667s
Is it the best version?
I wrote a small tool to generate C-style unions called unionize which you can find at https://github.com/zyedidia/unionize. You give it a template and then it will generate Go code that acts like a union and has comparable performance to C (warning: it uses the unsafe package, see the github repository for how it works and a detailed discussion of alternatives).
I copied your C benchmark into Go using unionize. First create a template for the union, for example in union.go:
package main
type Int struct {
i int32
v int16
}
Now use unionize to generate the actual union code which will go into a_union.go:
$ unionize -output=a_union.go Int union.go
This creates a new type IntUnion from the Int template which exposes functions to manipulate the union members. Now we can write the benchmark using that type:
package main
import "fmt"
type A struct {
t int
u IntUnion
}
func main() {
var a [2]A
a[0].t = 1
a[0].u.iPut(100)
a[1].t = 2
a[1].u.vPut(3)
var total int
for i := 0; i < 5000000000; i++ {
p := &a[i%2]
switch p.t {
case 1:
total += int(p.u.i())
case 2:
total += int(p.u.v())
}
}
fmt.Println(total)
}
When I time it I get:
$ go build main.go a_union.go
$ time ./main
257500000000
real 0m6.202s
user 0m6.197s
sys 0m0.012s
Not bad! (on my machine the C benchmark runs in roughly 3 seconds). The tool is fairly small, so let me know if there are more features you are looking for, or if you find any bugs.
Here is a solution which stores the union data as an interface{} and then uses a type switch to decide which data is stored in the union field:
package main
import "fmt"
type A struct {
u interface{}
}
func test() int64 {
a := []A{
{u: int32(100)},
{u: int16(3)},
}
total := int64(0)
for i := int64(0); i < 5000000000; i++ {
switch x := a[i%2].u.(type) {
case int32:
total += int64(x)
case int16:
total += int64(x)
}
}
return total
}
func main() {
total := test()
fmt.Println(total)
}
Due to the use of the type switch, the field t is not needed, making the code a bit tidier than the C version. This is still slower than the C code, but only by a factor of two.
C version:
257500000000
real 0m3.788s
user 0m3.776s
sys 0m0.011s
Go version:
257500000000
real 0m6.229s
user 0m6.211s
sys 0m0.019s

Returning values through the arguments of go function, which is called from C

Suppose, we've got a Go function, which is doing something with agruments, passed to them, e.g. it could fill the buffer, allocated in the C part and changing it and for example an integer argument, which is a size of read data. It works well with an integer one, but not with a "data part". Just see a code.
package main
/*
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
extern int some(uint8_t *, int *);
static int somewrap() {
uint8_t *i = malloc(16);
int A = 1;
int *x = &A;
some(i, x);
fprintf(stderr, "c.wrapper, i=%s, %p, x=%d, %p\n", i, i, *x, x);
return 0;
}
*/
import "C"
import "fmt"
import (
"unsafe"
)
//export some
func some(i *C.uint8_t, x *C.int) C.int {
fmt.Println("i:", i, &i, *i, "x:", x, &x, *x)
p := []byte("xxx")
i = (*C.uint8_t)(unsafe.Pointer(&p[0]))
*x = C.int(42)
fmt.Println("i:", i, &i, *i, "x:", x, &x, *x)
return C.int(0)
}
func main() {
C.somewrap()
}
As a result, we've got following:
i: 0x4303a40 0xc210000018 0 x: 0x7fff5fbff874 0xc210000020 1
i: 0xc210000038 0xc210000018 120 x: 0x7fff5fbff874 0xc210000020 42
c.wrapper, i=, 0x4303a40, x=42, 0x7fff5fbff874
As you can see, it works well for integer pointer, but not for uint8_t.
You're re-assigning i within some to another address, not change the value at the given address (unless I'm misunderstanding what you're trying to accomplish)
*i = *(*C.uint8_t)(unsafe.Pointer(&p[0]))

problems when accessing C union field

I'd like to access the field of C union in Go. below is my source code, but i got an error when compile it:
package main
// #include <stdio.h>
// #include <stdlib.h>
// union bar {
// char c;
// int i;
// double d;
// };
import "C"
import "fmt"
func main() {
var b *C.union_bar = new(C.union_bar)
b.c = 4
fmt.Println(b)
}
when i build, i got errors like below:
b.c undefined (type *[8]byte has no field or method c)
Who could tell me the correct approach to access a union field?
Seems like unions are treated, for type safety, as [N]byte, N == size of the biggest union item. Thus it is necessary to handle the "Go visible" type as [8]byte in this case. Then it appears to work:
package main
/*
#include <stdio.h>
#include <stdlib.h>
union bar {
char c;
int i;
double d;
} bar;
void foo(union bar *b) {
printf("%i\n", b->i);
};
*/
import "C"
import "fmt"
func main() {
b := new(C.union_bar)
b[0] = 1
b[1] = 2
C.foo(b)
fmt.Println(b)
}
(11:28) jnml#celsius:~/src/tmp/union$ go build && ./union
513
&[1 2 0 0 0 0 0 0]
(11:28) jnml#celsius:~/src/tmp/union$
Note: The same code would print a different number at a machine with other endianness.

Resources