SlideShare a Scribd company logo
1 of 86
Download to read offline
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Foreign Functions for
Fun and Profit
When and how to use CGo
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
github.com/liztio/cgo-demo
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
@stillinbeta
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
recurse.com
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Renee French. (http://reneefrench.blogspot.com/)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Full disclosure?
...I don’t actually like Go very much.
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
but I use it a lot
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Why not Cgo?
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
cgo is not Go - Dave Cheney
bit.ly/cgo-not-go
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Why not Cgo
● More complicated compilation
● Less portable
● No cross compilation
● More segfaults
● No backtraces
● Less tooling
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Why Cgo
● ...sometimes it’s the only way
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Calling C from Go
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
#include <stdint.h>
uint32_t add_one(uint32_t val);
addlib.h
#include "addlib.h"
uint32_t add_one(uint32_t val)
{
return val + 1;
}
addlib.c
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
uint32_t
Unsigned integer 32 bit type
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
import "C"
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
// #include "addlib.h"
import "C"
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
added := C.add_one(num)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
main.go
package main
// #include "addlib.h"
import "C" // “C” always gets its own line
import "fmt"
func main() {
num := 10
added := C.add_one(num)
fmt.Printf("%d + 1 is %d!n", num, added)
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ go run github.com/liztio/cgo-demo/cmd/c_from_go
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ go run github.com/liztio/cgo-demo/cmd/c_from_go
# github.com/liztio/cgo-demo/cmd/c_from_go
cmd/c_from_go/main.go:10:27: cannot use num (type
int) as type _Ctype_uint in argument to
_Cfunc_add_one
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
added := C.add_one(C.uint32_t(num))
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ go run github.com/liztio/cgo-demo/cmd/c_from_go
10 + 1 is 11!
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Calling Go from C
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
//export Greet
func Greet(chars *C.char) {
str := C.GoString(chars)
fmt.Printf("Hello from Go, %s!n", str)
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
//export Greet
func Greet(chars *C.char) {
str := C.GoString(chars)
fmt.Printf("Hello from Go, %s!n", str)
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
//export Greet
func Greet(chars *C.char) {
str := C.GoString(chars)
fmt.Printf("Hello from Go, %s!n", str)
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
F O S D E M x00
Strings in C
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
F O S D E M x00
46 4F 53 44 45 4d 00
Strings in C
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
F O S D E M
*ptr 6
Strings in Go
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
//export Greet
func Greet(chars *C.char) {
str := C.GoString(chars)
fmt.Printf("Hello from Go, %s!n", str)
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
package main
import "C"
import "fmt"
//export Greet
func Greet(chars *C.char) {
str := C.GoString(chars)
fmt.Printf("Hello from Go, %s!n", str)
}
func main() {} // required for main package
greet.go
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
main.c
#include "_cgo_export.h"
int main() {
char *name = "FOSDEM";
Greet(name);
return 0; // exit code
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
_cgo_export.h
/* Code generated by cmd/cgo; DO NOT EDIT. */
/* package main */
#line 1 "cgo-builtin-prolog"
#include <stddef.h> /* for ptrdiff_t below */
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
typedef struct { const char *p; ptrdiff_t n; }
_GoString_;
#endif
/* Start of preamble from import "C" comments.
*/
/* End of preamble from import "C" comments.
*/
/* Start of boilerplate cgo prologue. */
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
_cgo_export.h
/* don't worry about it */
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
A brief introduction to Makefiles
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
A brief introduction to Makefiles
all: output
output: input1 input2 input3
command --output $@ --inputs $^
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
A brief introduction to Makefiles
all: output
output: input1 input2 input3
command --output output --inputs input1 input2 input3
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Our Makefile
_cgo_export.h: greet.go
go tool cgo -exportheader $@ $^
greet.a: greet.go
go build -buildmode=c-archive $^
gofromc: main.c _cgo_export.h greet.a
$(CC) -o $@ $^ -lpthread
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Our Makefile
_cgo_export.h: greet.go
go tool cgo -exportheader $@ $^
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Our Makefile
greet.a: greet.go
go build -buildmode=c-archive $^
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Our Makefile
gofromc: main.c _cgo_export.h greet.a
$(CC) -o $@ $^ -lpthread
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ make
go tool cgo -exportheader _cgo_export.h greet.go
go build -buildmode=c-archive greet.go
cc -o gofromc main.c _cgo_export.h greet.a -lpthread
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Let’s try it out!
$ ./gofromc
Hello from Go, FOSDEM!
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Pointers and Memory
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Go Memory
● new() / &value
● Garbage Collected
● malloc()
● Manually Freed with free()
C Memory
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Allocating in Go
type Point struct {
x, y float32
}
func getPoint() *Point {
return &Point{
x: 10,
y: 12,
}
}
typedef struct {
float x;
float y;
} Point;
Point *getPoint() {
Point *pt = malloc(sizeof(Point));
pt->x = 10;
pt->y = 12;
return pt;
}
Allocating in C
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Go
func usePoint(pt *Point) {
fmt.Printf("x: %f, y: %fn", pt.x, pt.y)
// Goes out of scope
}
void usePoint(Point *pt) {
printf("x: %f, y: %fn", pt->x, pt->y);
free(pt);
}
C
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
What happens if you forget to free?
$ ./gofromc
x: 10.000000, y: 12.000000
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
What happens if you forget to free?
$ valgrind --leak-check=full ./gofromc
==7974== Memcheck, a memory error detector
==7974== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7974== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==7974== Command: ./gofromc
==7974==
x: 10.000000, y: 12.000000
==7974==
==7974== HEAP SUMMARY:
==7974== in use at exit: 8 bytes in 1 blocks
==7974== total heap usage: 2 allocs, 1 frees, 1,032 bytes allocated
==7974==
==7974== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7974== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7974== by 0x10869B: getPoint (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc)
==7974== by 0x10871C: main (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc)
==7974==
==7974== LEAK SUMMARY:
==7974== definitely lost: 8 bytes in 1 blocks
==7974== indirectly lost: 0 bytes in 0 blocks
==7974== possibly lost: 0 bytes in 0 blocks
==7974== still reachable: 0 bytes in 0 blocks
==7974== suppressed: 0 bytes in 0 blocks
==7974==
==7974== For counts of detected and suppressed errors, rerun with: -v
==7974== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
What happens if you forget to free?
$ valgrind --leak-check=full ./gofromc
==7974== Memcheck, a memory error detector
==7974== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7974== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==7974== Command: ./gofromc
==7974==
x: 10.000000, y: 12.000000
==7974==
==7974== HEAP SUMMARY:
==7974== in use at exit: 8 bytes in 1 blocks
==7974== total heap usage: 2 allocs, 1 frees, 1,032 bytes allocated
==7974==
==7974== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7974== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7974== by 0x10869B: getPoint (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc)
==7974== by 0x10871C: main (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc)
==7974==
==7974== LEAK SUMMARY:
==7974== definitely lost: 8 bytes in 1 blocks
==7974== indirectly lost: 0 bytes in 0 blocks
==7974== possibly lost: 0 bytes in 0 blocks
==7974== still reachable: 0 bytes in 0 blocks
==7974== suppressed: 0 bytes in 0 blocks
==7974==
==7974== For counts of detected and suppressed errors, rerun with: -v
==7974== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
What happens if you forget to free?
$ valgrind --leak-check=full ./gofromc
==7974== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7974== at 0x4C2FB0F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7974== by 0x10869B: getPoint (in
/home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc)
==7974== by 0x10871C: main (in
/home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Passing Pointers between
C and Go
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Okay
● Passing Go pointers to C
● Passing C pointers to Go
● Storing Go pointers in C memory before
returning
● A bunch of weird special cases involving
Java and Darwin
● Passing Go pointers with nested pointers
to C
● Storing Go pointers in Go memory from C
● Storing Go pointers in C memory
● Storing Go pointers in C memory after
returning
● Go Functions called by C returning Go
pointers
Invalid
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
tl;dr
● Pass pointers carefully
● Read the Cgo docs (golang.org/cmd/cgo)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
How about something
nontrivial?
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
How about a little magick?
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
#include <wand/magick_wand.h>
int main() {
MagickWand *mw = NULL;
MagickWandGenesis();
/* Create a wand */
mw = NewMagickWand();
/* Read the input image */
MagickReadImage(mw,"logo:");
/* write it */
MagickWriteImage(mw,"logo.jpg");
/* Tidy up */
if(mw) mw = DestroyMagickWand(mw);
MagickWandTerminus();
}
https://imagemagick.org/MagickWand/
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
package main
// #cgo pkg-config: MagickWand
// #include <wand/MagickWand.h>
import "C"
func main() {
C.MagickWandGenesis()
/* Create a wand */
mw := C.NewMagickWand()
defer func() {
/* Tidy up */
C.DestroyMagickWand(mw)
C.MagickWandTerminus()
}()
/* Read the input image */
C.MagickReadImage(mw, C.CString("logo:"))
/* write it */
C.MagickWriteImage(mw,
C.CString("logo.jpg"))
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
what’s this?
// #cgo pkg-config: MagickWand
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ pkg-config MagickWand --cflags
-fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -fopenmp -DMAGICKCORE_
$ pkg-config MagickWand --libs
-lMagickWand-6.Q16 -lMagickCore-6.Q16
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Expands to
// #cgo CFLAGS: -I/usr/include/ImageMagick-6 -I/usr/include/x86_64-linux-gnu/ImageMagick-6
// #cgo LDFLAGS: -lMagickWand-6.Q16 -lMagickCore-6.Q16
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
C defer anyone?
defer func() {
/* Tidy up */
C.DestroyMagickWand(mw)
C.MagickWandTerminus()
}()
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Full resizing demo in the Github Repo!
github.com/liztio/cgo-demo/cmd/imagemagick
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Dynamic Libraries
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
“Go binaries are
static”
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Windows OSX Linux
.dll .dylib .so
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
int localFunc() {
return 0;
}
int main() {
return localFunc();
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
main 0x0000000000000605
localFunction 0x00000000000005fa
mybinary
int localFunc() {
return 0;
}
int main() {
return localFunc();
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
#include <lib1.h>
#include <lib2.h>
void localFunction() {
char *str = lib1Func1();
lib2Func2(str);
}
int main() {
localFunction()
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
main.main 0x00000000004891d0
localFunction 0x0000000000489985
lib1func1
lib2func2
mybinary
#include <lib1.h>
#include <lib2.h>
void localFunction() {
char *str = lib1Func1();
lib2Func2(str);
}
int main() {
localFunction()
}
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
main.main 0x00000000004891d0
localFunction 0x0000000000489985
lib1func1
lib2func2
lib1func0 0x00000000004891d0
lib1func1 0x0000000000489985
lib1func2 0x0000000000489985
lib2func0 0x0000000000455ea0
lib2func1 0x000000000073f598
lib2func2 0x000000000073f598
lib1.so
lib2.so
mybinary
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
LDD(1) Linux Programmer's Manual LDD(1)
NAME
ldd - print shared object dependencies
SYNOPSIS
ldd [option]... file...
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ ldd ~/bin/ginkgo
linux-vdso.so.1 (0x00007ffc71493000)
libpthread.so.0 =>
/lib/x86_64-linux-gnu/libpthread.so.0
(0x00007fa2d36c4000)
libc.so.6 =>
/lib/x86_64-linux-gnu/libc.so.6
(0x00007fa2d32d3000)
/lib64/ld-linux-x86-64.so.2
(0x00007fa2d38e3000)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ ldd ~/bin/ginkgo
linux-vdso.so.1 (0x00007ffc71493000)
libpthread.so.0 =>
/lib/x86_64-linux-gnu/libpthread.so.0
(0x00007fa2d36c4000)
libc.so.6 =>
/lib/x86_64-linux-gnu/libc.so.6
(0x00007fa2d32d3000)
/lib64/ld-linux-x86-64.so.2
(0x00007fa2d38e3000)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
// #cgo LDFLAGS: -laddlib
// #include "addlib.h"
import "C"
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ go install github.com/liztio/cgo-demo/cmd/addbin
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ export ADDLIB_DIR=/home/liz/src/github.com/liztio/cgo-demo/src/addlib
$ export CGO_CFLAGS=-I$ADDLIB_DIR
$ export CGO_LDFLAGS=-L$ADDLIB_DIR
$ go install github.com/liztio/cgo-demo/cmd/addbin
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ export ADDLIB_DIR=/home/liz/src/github.com/liztio/cgo-demo/src/addlib
$ export CGO_CFLAGS=-I$ADDLIB_DIR
$ export CGO_LDFLAGS=-L$ADDLIB_DIR
$ go install github.com/liztio/cgo-demo/cmd/addbin
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ ldd addbin
linux-vdso.so.1 (0x00007ffd2b966000)
libaddlib.so => not found
libpthread.so.0 =>
/lib/x86_64-linux-gnu/libpthread.so.0
(0x00007f252a003000)
libc.so.6 =>
/lib/x86_64-linux-gnu/libc.so.6
(0x00007f2529c12000)
/lib64/ld-linux-x86-64.so.2
(0x00007f252a222000)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ ldd addbin
linux-vdso.so.1 (0x00007ffd2b966000)
libaddlib.so => not found
libpthread.so.0 =>
/lib/x86_64-linux-gnu/libpthread.so.0
(0x00007f252a003000)
libc.so.6 =>
/lib/x86_64-linux-gnu/libc.so.6
(0x00007f2529c12000)
/lib64/ld-linux-x86-64.so.2
(0x00007f252a222000)
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ addbin
addbin: error while loading shared libraries:
libaddlib.so: cannot open shared object file:
No such file or directory
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
$ LD_LIBRARY_PATH=$ADDLIB_DIR addbin
Go says: 11 + one is 12
github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta
Questions?
Please play with the code!
github.com/liztio/cgo-demo

More Related Content

Similar to CGo for fun and profit

GIT training - advanced for software projects
GIT training - advanced for software projectsGIT training - advanced for software projects
GIT training - advanced for software projectsThierry Gayet
 
Understanding Pseudo-Versions Moving to Go 1.13 What is in Go 1.14+ for Modules
Understanding Pseudo-Versions Moving to Go 1.13 What is in Go 1.14+ for ModulesUnderstanding Pseudo-Versions Moving to Go 1.13 What is in Go 1.14+ for Modules
Understanding Pseudo-Versions Moving to Go 1.13 What is in Go 1.14+ for ModulesMitali Bisht
 
Pseudo-versions, moving to Go1.13 and later versions
Pseudo-versions, moving to Go1.13 and later versionsPseudo-versions, moving to Go1.13 and later versions
Pseudo-versions, moving to Go1.13 and later versionsMitali Bisht
 
Eta lang Beauty And The Beast
Eta lang Beauty And The Beast Eta lang Beauty And The Beast
Eta lang Beauty And The Beast Jarek Ratajski
 
나도 할 수 있다 오픈소스
나도 할 수 있다 오픈소스나도 할 수 있다 오픈소스
나도 할 수 있다 오픈소스효준 강
 
Goの標準的な開発の流れ
Goの標準的な開発の流れGoの標準的な開発の流れ
Goの標準的な開発の流れRyuji Iwata
 
Golang 101 for IT-Pros - Cisco Live Orlando 2018 - DEVNET-1808
Golang 101 for IT-Pros - Cisco Live Orlando 2018 - DEVNET-1808Golang 101 for IT-Pros - Cisco Live Orlando 2018 - DEVNET-1808
Golang 101 for IT-Pros - Cisco Live Orlando 2018 - DEVNET-1808Cisco DevNet
 
[MeetUp][2nd] 컭on턺
[MeetUp][2nd] 컭on턺[MeetUp][2nd] 컭on턺
[MeetUp][2nd] 컭on턺InfraEngineer
 
JAZOON'13 - Thomas Hug & Bartosz Majsak - Git Workshop -Essentials
JAZOON'13 - Thomas Hug & Bartosz Majsak - Git Workshop -EssentialsJAZOON'13 - Thomas Hug & Bartosz Majsak - Git Workshop -Essentials
JAZOON'13 - Thomas Hug & Bartosz Majsak - Git Workshop -Essentialsjazoon13
 
You got database in my cloud!
You got database  in my cloud!You got database  in my cloud!
You got database in my cloud!Liz Frost
 
Git workflows presentation
Git workflows presentationGit workflows presentation
Git workflows presentationMack Hardy
 
Git single branch
Git single branchGit single branch
Git single branchCarl Brown
 
Develop Android app using Golang
Develop Android app using GolangDevelop Android app using Golang
Develop Android app using GolangSeongJae Park
 

Similar to CGo for fun and profit (20)

GIT training - advanced for software projects
GIT training - advanced for software projectsGIT training - advanced for software projects
GIT training - advanced for software projects
 
Understanding Pseudo-Versions Moving to Go 1.13 What is in Go 1.14+ for Modules
Understanding Pseudo-Versions Moving to Go 1.13 What is in Go 1.14+ for ModulesUnderstanding Pseudo-Versions Moving to Go 1.13 What is in Go 1.14+ for Modules
Understanding Pseudo-Versions Moving to Go 1.13 What is in Go 1.14+ for Modules
 
Pseudo-versions, moving to Go1.13 and later versions
Pseudo-versions, moving to Go1.13 and later versionsPseudo-versions, moving to Go1.13 and later versions
Pseudo-versions, moving to Go1.13 and later versions
 
Evolution and AI
Evolution and AIEvolution and AI
Evolution and AI
 
Eta lang Beauty And The Beast
Eta lang Beauty And The Beast Eta lang Beauty And The Beast
Eta lang Beauty And The Beast
 
나도 할 수 있다 오픈소스
나도 할 수 있다 오픈소스나도 할 수 있다 오픈소스
나도 할 수 있다 오픈소스
 
Goの標準的な開発の流れ
Goの標準的な開発の流れGoの標準的な開発の流れ
Goの標準的な開発の流れ
 
How to build the Web
How to build the WebHow to build the Web
How to build the Web
 
Golang 101 for IT-Pros - Cisco Live Orlando 2018 - DEVNET-1808
Golang 101 for IT-Pros - Cisco Live Orlando 2018 - DEVNET-1808Golang 101 for IT-Pros - Cisco Live Orlando 2018 - DEVNET-1808
Golang 101 for IT-Pros - Cisco Live Orlando 2018 - DEVNET-1808
 
[MeetUp][2nd] 컭on턺
[MeetUp][2nd] 컭on턺[MeetUp][2nd] 컭on턺
[MeetUp][2nd] 컭on턺
 
JAZOON'13 - Thomas Hug & Bartosz Majsak - Git Workshop -Essentials
JAZOON'13 - Thomas Hug & Bartosz Majsak - Git Workshop -EssentialsJAZOON'13 - Thomas Hug & Bartosz Majsak - Git Workshop -Essentials
JAZOON'13 - Thomas Hug & Bartosz Majsak - Git Workshop -Essentials
 
You got database in my cloud!
You got database  in my cloud!You got database  in my cloud!
You got database in my cloud!
 
Git workflows presentation
Git workflows presentationGit workflows presentation
Git workflows presentation
 
Hom Class
Hom ClassHom Class
Hom Class
 
Hom Class
Hom ClassHom Class
Hom Class
 
Hom Class
Hom ClassHom Class
Hom Class
 
C++ Core Guidelines
C++ Core GuidelinesC++ Core Guidelines
C++ Core Guidelines
 
Xdebug
XdebugXdebug
Xdebug
 
Git single branch
Git single branchGit single branch
Git single branch
 
Develop Android app using Golang
Develop Android app using GolangDevelop Android app using Golang
Develop Android app using Golang
 

Recently uploaded

Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerStudy on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerAnamika Sarkar
 
welding defects observed during the welding
welding defects observed during the weldingwelding defects observed during the welding
welding defects observed during the weldingMuhammadUzairLiaqat
 
Software and Systems Engineering Standards: Verification and Validation of Sy...
Software and Systems Engineering Standards: Verification and Validation of Sy...Software and Systems Engineering Standards: Verification and Validation of Sy...
Software and Systems Engineering Standards: Verification and Validation of Sy...VICTOR MAESTRE RAMIREZ
 
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETEINFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETEroselinkalist12
 
Electronically Controlled suspensions system .pdf
Electronically Controlled suspensions system .pdfElectronically Controlled suspensions system .pdf
Electronically Controlled suspensions system .pdfme23b1001
 
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)dollysharma2066
 
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdfCCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdfAsst.prof M.Gokilavani
 
Piping Basic stress analysis by engineering
Piping Basic stress analysis by engineeringPiping Basic stress analysis by engineering
Piping Basic stress analysis by engineeringJuanCarlosMorales19600
 
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort serviceGurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort servicejennyeacort
 
complete construction, environmental and economics information of biomass com...
complete construction, environmental and economics information of biomass com...complete construction, environmental and economics information of biomass com...
complete construction, environmental and economics information of biomass com...asadnawaz62
 
Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.eptoze12
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile servicerehmti665
 
Class 1 | NFPA 72 | Overview Fire Alarm System
Class 1 | NFPA 72 | Overview Fire Alarm SystemClass 1 | NFPA 72 | Overview Fire Alarm System
Class 1 | NFPA 72 | Overview Fire Alarm Systemirfanmechengr
 
Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024hassan khalil
 
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionSachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionDr.Costas Sachpazis
 
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfCCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfAsst.prof M.Gokilavani
 

Recently uploaded (20)

Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerStudy on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
 
welding defects observed during the welding
welding defects observed during the weldingwelding defects observed during the welding
welding defects observed during the welding
 
Software and Systems Engineering Standards: Verification and Validation of Sy...
Software and Systems Engineering Standards: Verification and Validation of Sy...Software and Systems Engineering Standards: Verification and Validation of Sy...
Software and Systems Engineering Standards: Verification and Validation of Sy...
 
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
 
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETEINFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
 
Electronically Controlled suspensions system .pdf
Electronically Controlled suspensions system .pdfElectronically Controlled suspensions system .pdf
Electronically Controlled suspensions system .pdf
 
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
 
POWER SYSTEMS-1 Complete notes examples
POWER SYSTEMS-1 Complete notes  examplesPOWER SYSTEMS-1 Complete notes  examples
POWER SYSTEMS-1 Complete notes examples
 
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptxExploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
Exploring_Network_Security_with_JA3_by_Rakesh Seal.pptx
 
Design and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdfDesign and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdf
 
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdfCCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
CCS355 Neural Networks & Deep Learning Unit 1 PDF notes with Question bank .pdf
 
Piping Basic stress analysis by engineering
Piping Basic stress analysis by engineeringPiping Basic stress analysis by engineering
Piping Basic stress analysis by engineering
 
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort serviceGurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
Gurgaon ✡️9711147426✨Call In girls Gurgaon Sector 51 escort service
 
complete construction, environmental and economics information of biomass com...
complete construction, environmental and economics information of biomass com...complete construction, environmental and economics information of biomass com...
complete construction, environmental and economics information of biomass com...
 
Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile service
 
Class 1 | NFPA 72 | Overview Fire Alarm System
Class 1 | NFPA 72 | Overview Fire Alarm SystemClass 1 | NFPA 72 | Overview Fire Alarm System
Class 1 | NFPA 72 | Overview Fire Alarm System
 
Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024
 
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionSachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
 
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdfCCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
CCS355 Neural Network & Deep Learning Unit II Notes with Question bank .pdf
 

CGo for fun and profit

  • 1. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Foreign Functions for Fun and Profit When and how to use CGo
  • 2. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta github.com/liztio/cgo-demo
  • 5. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta @stillinbeta
  • 7. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta recurse.com
  • 8. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Renee French. (http://reneefrench.blogspot.com/)
  • 9. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Full disclosure? ...I don’t actually like Go very much.
  • 10. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta but I use it a lot
  • 11. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Why not Cgo?
  • 12. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta cgo is not Go - Dave Cheney bit.ly/cgo-not-go
  • 13. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Why not Cgo ● More complicated compilation ● Less portable ● No cross compilation ● More segfaults ● No backtraces ● Less tooling
  • 14. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Why Cgo ● ...sometimes it’s the only way
  • 15. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Calling C from Go
  • 16. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta #include <stdint.h> uint32_t add_one(uint32_t val); addlib.h #include "addlib.h" uint32_t add_one(uint32_t val) { return val + 1; } addlib.c
  • 17. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta uint32_t Unsigned integer 32 bit type
  • 18. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta import "C"
  • 19. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta // #include "addlib.h" import "C"
  • 20. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta added := C.add_one(num)
  • 21. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta main.go package main // #include "addlib.h" import "C" // “C” always gets its own line import "fmt" func main() { num := 10 added := C.add_one(num) fmt.Printf("%d + 1 is %d!n", num, added) }
  • 22. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ go run github.com/liztio/cgo-demo/cmd/c_from_go
  • 23. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ go run github.com/liztio/cgo-demo/cmd/c_from_go # github.com/liztio/cgo-demo/cmd/c_from_go cmd/c_from_go/main.go:10:27: cannot use num (type int) as type _Ctype_uint in argument to _Cfunc_add_one
  • 24. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta added := C.add_one(C.uint32_t(num))
  • 25. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ go run github.com/liztio/cgo-demo/cmd/c_from_go 10 + 1 is 11!
  • 26. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Calling Go from C
  • 27. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta //export Greet func Greet(chars *C.char) { str := C.GoString(chars) fmt.Printf("Hello from Go, %s!n", str) }
  • 28. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta //export Greet func Greet(chars *C.char) { str := C.GoString(chars) fmt.Printf("Hello from Go, %s!n", str) }
  • 29. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta //export Greet func Greet(chars *C.char) { str := C.GoString(chars) fmt.Printf("Hello from Go, %s!n", str) }
  • 30. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta F O S D E M x00 Strings in C
  • 31. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta F O S D E M x00 46 4F 53 44 45 4d 00 Strings in C
  • 32. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta F O S D E M *ptr 6 Strings in Go
  • 33. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta //export Greet func Greet(chars *C.char) { str := C.GoString(chars) fmt.Printf("Hello from Go, %s!n", str) }
  • 34. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta package main import "C" import "fmt" //export Greet func Greet(chars *C.char) { str := C.GoString(chars) fmt.Printf("Hello from Go, %s!n", str) } func main() {} // required for main package greet.go
  • 35. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta main.c #include "_cgo_export.h" int main() { char *name = "FOSDEM"; Greet(name); return 0; // exit code }
  • 36. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta _cgo_export.h /* Code generated by cmd/cgo; DO NOT EDIT. */ /* package main */ #line 1 "cgo-builtin-prolog" #include <stddef.h> /* for ptrdiff_t below */ #ifndef GO_CGO_EXPORT_PROLOGUE_H #define GO_CGO_EXPORT_PROLOGUE_H typedef struct { const char *p; ptrdiff_t n; } _GoString_; #endif /* Start of preamble from import "C" comments. */ /* End of preamble from import "C" comments. */ /* Start of boilerplate cgo prologue. */
  • 37. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta _cgo_export.h /* don't worry about it */
  • 38. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta A brief introduction to Makefiles
  • 39. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta A brief introduction to Makefiles all: output output: input1 input2 input3 command --output $@ --inputs $^
  • 40. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta A brief introduction to Makefiles all: output output: input1 input2 input3 command --output output --inputs input1 input2 input3
  • 41. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Our Makefile _cgo_export.h: greet.go go tool cgo -exportheader $@ $^ greet.a: greet.go go build -buildmode=c-archive $^ gofromc: main.c _cgo_export.h greet.a $(CC) -o $@ $^ -lpthread
  • 42. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Our Makefile _cgo_export.h: greet.go go tool cgo -exportheader $@ $^
  • 43. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Our Makefile greet.a: greet.go go build -buildmode=c-archive $^
  • 44. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Our Makefile gofromc: main.c _cgo_export.h greet.a $(CC) -o $@ $^ -lpthread
  • 45. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ make go tool cgo -exportheader _cgo_export.h greet.go go build -buildmode=c-archive greet.go cc -o gofromc main.c _cgo_export.h greet.a -lpthread
  • 46. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Let’s try it out! $ ./gofromc Hello from Go, FOSDEM!
  • 47. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Pointers and Memory
  • 48. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Go Memory ● new() / &value ● Garbage Collected ● malloc() ● Manually Freed with free() C Memory
  • 49. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Allocating in Go type Point struct { x, y float32 } func getPoint() *Point { return &Point{ x: 10, y: 12, } } typedef struct { float x; float y; } Point; Point *getPoint() { Point *pt = malloc(sizeof(Point)); pt->x = 10; pt->y = 12; return pt; } Allocating in C
  • 50. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Go func usePoint(pt *Point) { fmt.Printf("x: %f, y: %fn", pt.x, pt.y) // Goes out of scope } void usePoint(Point *pt) { printf("x: %f, y: %fn", pt->x, pt->y); free(pt); } C
  • 51. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta What happens if you forget to free? $ ./gofromc x: 10.000000, y: 12.000000
  • 52. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta What happens if you forget to free? $ valgrind --leak-check=full ./gofromc ==7974== Memcheck, a memory error detector ==7974== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==7974== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==7974== Command: ./gofromc ==7974== x: 10.000000, y: 12.000000 ==7974== ==7974== HEAP SUMMARY: ==7974== in use at exit: 8 bytes in 1 blocks ==7974== total heap usage: 2 allocs, 1 frees, 1,032 bytes allocated ==7974== ==7974== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==7974== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7974== by 0x10869B: getPoint (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc) ==7974== by 0x10871C: main (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc) ==7974== ==7974== LEAK SUMMARY: ==7974== definitely lost: 8 bytes in 1 blocks ==7974== indirectly lost: 0 bytes in 0 blocks ==7974== possibly lost: 0 bytes in 0 blocks ==7974== still reachable: 0 bytes in 0 blocks ==7974== suppressed: 0 bytes in 0 blocks ==7974== ==7974== For counts of detected and suppressed errors, rerun with: -v ==7974== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  • 53. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta What happens if you forget to free? $ valgrind --leak-check=full ./gofromc ==7974== Memcheck, a memory error detector ==7974== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==7974== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==7974== Command: ./gofromc ==7974== x: 10.000000, y: 12.000000 ==7974== ==7974== HEAP SUMMARY: ==7974== in use at exit: 8 bytes in 1 blocks ==7974== total heap usage: 2 allocs, 1 frees, 1,032 bytes allocated ==7974== ==7974== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==7974== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7974== by 0x10869B: getPoint (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc) ==7974== by 0x10871C: main (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc) ==7974== ==7974== LEAK SUMMARY: ==7974== definitely lost: 8 bytes in 1 blocks ==7974== indirectly lost: 0 bytes in 0 blocks ==7974== possibly lost: 0 bytes in 0 blocks ==7974== still reachable: 0 bytes in 0 blocks ==7974== suppressed: 0 bytes in 0 blocks ==7974== ==7974== For counts of detected and suppressed errors, rerun with: -v ==7974== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  • 54. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta What happens if you forget to free? $ valgrind --leak-check=full ./gofromc ==7974== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==7974== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7974== by 0x10869B: getPoint (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc) ==7974== by 0x10871C: main (in /home/liz/src/github.com/liztio/cgo-demo/src/gofromc/gofromc)
  • 55. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Passing Pointers between C and Go
  • 56. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Okay ● Passing Go pointers to C ● Passing C pointers to Go ● Storing Go pointers in C memory before returning ● A bunch of weird special cases involving Java and Darwin ● Passing Go pointers with nested pointers to C ● Storing Go pointers in Go memory from C ● Storing Go pointers in C memory ● Storing Go pointers in C memory after returning ● Go Functions called by C returning Go pointers Invalid
  • 57. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta tl;dr ● Pass pointers carefully ● Read the Cgo docs (golang.org/cmd/cgo)
  • 58. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta How about something nontrivial?
  • 59. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta How about a little magick?
  • 60. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta #include <wand/magick_wand.h> int main() { MagickWand *mw = NULL; MagickWandGenesis(); /* Create a wand */ mw = NewMagickWand(); /* Read the input image */ MagickReadImage(mw,"logo:"); /* write it */ MagickWriteImage(mw,"logo.jpg"); /* Tidy up */ if(mw) mw = DestroyMagickWand(mw); MagickWandTerminus(); } https://imagemagick.org/MagickWand/
  • 61. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta package main // #cgo pkg-config: MagickWand // #include <wand/MagickWand.h> import "C" func main() { C.MagickWandGenesis() /* Create a wand */ mw := C.NewMagickWand() defer func() { /* Tidy up */ C.DestroyMagickWand(mw) C.MagickWandTerminus() }() /* Read the input image */ C.MagickReadImage(mw, C.CString("logo:")) /* write it */ C.MagickWriteImage(mw, C.CString("logo.jpg")) }
  • 62. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta what’s this? // #cgo pkg-config: MagickWand
  • 63. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ pkg-config MagickWand --cflags -fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -fopenmp -DMAGICKCORE_ $ pkg-config MagickWand --libs -lMagickWand-6.Q16 -lMagickCore-6.Q16
  • 64. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Expands to // #cgo CFLAGS: -I/usr/include/ImageMagick-6 -I/usr/include/x86_64-linux-gnu/ImageMagick-6 // #cgo LDFLAGS: -lMagickWand-6.Q16 -lMagickCore-6.Q16
  • 65. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta C defer anyone? defer func() { /* Tidy up */ C.DestroyMagickWand(mw) C.MagickWandTerminus() }()
  • 66. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Full resizing demo in the Github Repo! github.com/liztio/cgo-demo/cmd/imagemagick
  • 67. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Dynamic Libraries
  • 68. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta “Go binaries are static”
  • 69. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Windows OSX Linux .dll .dylib .so
  • 70. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta int localFunc() { return 0; } int main() { return localFunc(); }
  • 71. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta main 0x0000000000000605 localFunction 0x00000000000005fa mybinary int localFunc() { return 0; } int main() { return localFunc(); }
  • 72. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta #include <lib1.h> #include <lib2.h> void localFunction() { char *str = lib1Func1(); lib2Func2(str); } int main() { localFunction() }
  • 73. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta main.main 0x00000000004891d0 localFunction 0x0000000000489985 lib1func1 lib2func2 mybinary #include <lib1.h> #include <lib2.h> void localFunction() { char *str = lib1Func1(); lib2Func2(str); } int main() { localFunction() }
  • 74. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta main.main 0x00000000004891d0 localFunction 0x0000000000489985 lib1func1 lib2func2 lib1func0 0x00000000004891d0 lib1func1 0x0000000000489985 lib1func2 0x0000000000489985 lib2func0 0x0000000000455ea0 lib2func1 0x000000000073f598 lib2func2 0x000000000073f598 lib1.so lib2.so mybinary
  • 75. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta LDD(1) Linux Programmer's Manual LDD(1) NAME ldd - print shared object dependencies SYNOPSIS ldd [option]... file...
  • 76. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ ldd ~/bin/ginkgo linux-vdso.so.1 (0x00007ffc71493000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa2d36c4000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa2d32d3000) /lib64/ld-linux-x86-64.so.2 (0x00007fa2d38e3000)
  • 77. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ ldd ~/bin/ginkgo linux-vdso.so.1 (0x00007ffc71493000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa2d36c4000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa2d32d3000) /lib64/ld-linux-x86-64.so.2 (0x00007fa2d38e3000)
  • 78. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta // #cgo LDFLAGS: -laddlib // #include "addlib.h" import "C"
  • 79. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ go install github.com/liztio/cgo-demo/cmd/addbin
  • 80. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ export ADDLIB_DIR=/home/liz/src/github.com/liztio/cgo-demo/src/addlib $ export CGO_CFLAGS=-I$ADDLIB_DIR $ export CGO_LDFLAGS=-L$ADDLIB_DIR $ go install github.com/liztio/cgo-demo/cmd/addbin
  • 81. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ export ADDLIB_DIR=/home/liz/src/github.com/liztio/cgo-demo/src/addlib $ export CGO_CFLAGS=-I$ADDLIB_DIR $ export CGO_LDFLAGS=-L$ADDLIB_DIR $ go install github.com/liztio/cgo-demo/cmd/addbin
  • 82. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ ldd addbin linux-vdso.so.1 (0x00007ffd2b966000) libaddlib.so => not found libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f252a003000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2529c12000) /lib64/ld-linux-x86-64.so.2 (0x00007f252a222000)
  • 83. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ ldd addbin linux-vdso.so.1 (0x00007ffd2b966000) libaddlib.so => not found libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f252a003000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2529c12000) /lib64/ld-linux-x86-64.so.2 (0x00007f252a222000)
  • 84. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ addbin addbin: error while loading shared libraries: libaddlib.so: cannot open shared object file: No such file or directory
  • 85. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta $ LD_LIBRARY_PATH=$ADDLIB_DIR addbin Go says: 11 + one is 12
  • 86. github.com/liztio/cgo-demo // #FOSDEM 2019 // @stillinbeta Questions? Please play with the code! github.com/liztio/cgo-demo