images: 针对cgo生成一些图片
31
images/Makefile
Normal file
@ -0,0 +1,31 @@
|
||||
# Copyright 2017 <chaishushan{AT}gmail.com>. All rights reserved.
|
||||
# Use of this source code is governed by a Apache
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
UML_FILES=$(wildcard ./*.plantuml)
|
||||
UML_SVG_FILES=$(patsubst %.plantuml,%.uml.svg,$(UML_FILES))
|
||||
UML_PNG_FILES=$(patsubst %.plantuml,%.uml.png,$(UML_FILES))
|
||||
|
||||
DOT_FILES=$(wildcard ./*.dot)
|
||||
DOT_PNG_FILES=$(patsubst %.dot,%.dot.png,$(DOT_FILES))
|
||||
|
||||
default: $(UML_PNG_FILES) $(DOT_PNG_FILES)
|
||||
@echo "ok"
|
||||
|
||||
logo:
|
||||
convert logo-2018-01.png -resize 300x65 logo.png
|
||||
@echo "ok"
|
||||
|
||||
clean:
|
||||
-rm *.dot.png
|
||||
-rm *.uml.png
|
||||
-rm *.uml.svg
|
||||
|
||||
%.uml.svg: %.plantuml
|
||||
cat $< | docker run --rm -i chai2010/ibox:plantuml > $@
|
||||
|
||||
%.uml.png: %.plantuml
|
||||
cat $< | docker run --rm -i chai2010/ibox:plantuml -tpng > $@
|
||||
|
||||
%.dot.png: %.dot
|
||||
dot -Tpng -o $@ $<
|
BIN
images/ch1-01-go-family-tree-x.dot.png
Normal file
After Width: | Height: | Size: 10 KiB |
46
images/ch2-call-c-sum-v1.plantuml
Normal file
@ -0,0 +1,46 @@
|
||||
' Copyright 2017 <chaishushan{AT}gmail.com>. All rights reserved.
|
||||
' Use of this source code is governed by a Apache
|
||||
' license that can be found in the LICENSE file.
|
||||
|
||||
@startuml
|
||||
|
||||
title C.sum(2, 3)
|
||||
|
||||
|main.go|
|
||||
:func main() {
|
||||
C.sum(2, 3))
|
||||
};
|
||||
|
||||
|#AntiqueWhite|main.cgo1.go|
|
||||
:func main() {
|
||||
_Cfunc_sum(2, 3))
|
||||
};
|
||||
|
||||
|#AntiqueWhite|_cgo_types.go|
|
||||
:func _Cfunc_sum(2, 3) double {
|
||||
_cgo_runtime_cgocall(...)
|
||||
return
|
||||
};
|
||||
|
||||
|runtime.cgocall|
|
||||
:_cgo_runtime_cgocall(...);
|
||||
|
||||
fork
|
||||
|
||||
|#AntiqueWhite|main.cgo2.c|
|
||||
: double _cgo_xxx_Cfunc_sum(2, 3) {
|
||||
return sum(2, 3)
|
||||
};
|
||||
|
||||
|#AntiqueWhite|_cgo_export.c|
|
||||
:sum(2, 3);
|
||||
|
||||
endfork
|
||||
|
||||
|runtime.cgocall|
|
||||
:_cgo_runtime_cgocall(...);
|
||||
|
||||
|main.go|
|
||||
stop
|
||||
|
||||
@enduml
|
BIN
images/ch2-call-c-sum-v1.uml.png
Normal file
After Width: | Height: | Size: 38 KiB |
63
images/ch2-call-c-sum-v2.plantuml
Normal file
@ -0,0 +1,63 @@
|
||||
' Copyright 2017 <chaishushan{AT}gmail.com>. All rights reserved.
|
||||
' Use of this source code is governed by a Apache
|
||||
' license that can be found in the LICENSE file.
|
||||
|
||||
@startuml
|
||||
|
||||
title c call go func
|
||||
|
||||
|_testmain.c|
|
||||
:int main() {
|
||||
extern int sum(int a, int b)
|
||||
sum(1, 2)
|
||||
return 0
|
||||
};
|
||||
-[#green,dashed]->
|
||||
|
||||
fork
|
||||
|
||||
|#AntiqueWhite|_cgo_export.c|
|
||||
:int sum(int p0, int p1) {
|
||||
struct { int p0, p1, r0; } a
|
||||
_cgo_ctxt = _cgo_wait_runtime_init_done()
|
||||
crosscall2(_cgoexp_xxx_sum, &a, 16, _cgo_ctxt)
|
||||
_cgo_release_context(_cgo_ctxt)
|
||||
return a.r0
|
||||
};
|
||||
|
||||
|runtime/cgo/*.asm|
|
||||
:TEXT crosscall2(SB),NOSPLIT,$0;
|
||||
|
||||
fork
|
||||
|
||||
|#AntiqueWhite|_cgo_types.go|
|
||||
:func _cgoexp_xxx_sum(a unsafe.Pointer, n int32, ctxt uintptr) {
|
||||
fn := _cgoexpwrap_xxx_sum
|
||||
_cgo_runtime_cgocallback(
|
||||
_cgoexpwrap_xxx_sum,
|
||||
...
|
||||
)
|
||||
};
|
||||
|
||||
|#AntiqueWhite|_cgo_types.go|
|
||||
:func _cgoexpwrap_xxx_sum(p0, p1) r0 {
|
||||
return sum(p0, p1)
|
||||
};
|
||||
|
||||
|main.go|
|
||||
://export sum
|
||||
func sum(a, b C.int) C.int {
|
||||
return a + b
|
||||
};
|
||||
|
||||
endfork
|
||||
|
||||
|runtime/cgo/*.asm|
|
||||
:TEXT crosscall2(SB),NOSPLIT,$0;
|
||||
|
||||
endfork
|
||||
|
||||
|_testmain.c|
|
||||
stop
|
||||
|
||||
@enduml
|
BIN
images/ch2-call-c-sum-v2.uml.png
Normal file
After Width: | Height: | Size: 56 KiB |
37
images/ch2-cgo-generated-files.dot
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2018 <chaishushan{AT}gmail.com>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
digraph G {
|
||||
subgraph cluster_cgo_package_main {
|
||||
label = "package main";
|
||||
|
||||
nocgo_x[label="nocgo_x.go", style=filled, color=gray];
|
||||
hello_go[label="hello.go", style=filled, color=orangered4];
|
||||
main_go[label="main.go", style=filled, color=darkgreen];
|
||||
nocgo_1[label="nocgo_1.go", style=filled, color=gray];
|
||||
}
|
||||
|
||||
subgraph cluster_cgo_generated_files {
|
||||
label = "cgo: generated fileds";
|
||||
|
||||
main_cgo2_c[label="main.cgo2.c", style=filled, color=green];
|
||||
main_cgo1_go[label="main.cgo1.go", style=filled, color=green];
|
||||
|
||||
hello_cgo2_c[label="hello.cgo2.c", style=filled, color=red];
|
||||
hello_cgo1_go[label="hello.cgo1.go", style=filled, color=red];
|
||||
|
||||
_cgo_gotypes_go[label="_cgo_gotypes.go", shape=box, style=filled, color=dodgerblue];
|
||||
_cgo_export_h[label="_cgo_export.h", shape=box, style=filled, color=dodgerblue];
|
||||
_cgo_export_c[label="_cgo_export.c", shape=box, style=filled, color=dodgerblue];
|
||||
|
||||
main_go -> main_cgo1_go -> _cgo_gotypes_go;
|
||||
main_go -> main_cgo2_c -> _cgo_gotypes_go;
|
||||
|
||||
hello_go -> hello_cgo1_go -> _cgo_gotypes_go;
|
||||
hello_go -> hello_cgo2_c -> _cgo_gotypes_go;
|
||||
|
||||
_cgo_gotypes_go -> _cgo_export_h;
|
||||
_cgo_gotypes_go -> _cgo_export_c;
|
||||
}
|
||||
}
|
BIN
images/ch2-cgo-generated-files.dot.png
Normal file
After Width: | Height: | Size: 50 KiB |
29
images/ch2-int32-to-char-ptr.plantuml
Normal file
@ -0,0 +1,29 @@
|
||||
' Copyright 2017 <chaishushan{AT}gmail.com>. All rights reserved.
|
||||
' Use of this source code is governed by a Apache
|
||||
' license that can be found in the LICENSE file.
|
||||
|
||||
@startuml
|
||||
|
||||
title int32 <=> *C.char
|
||||
|
||||
participant int32
|
||||
participant uintptr
|
||||
participant unsafe.Pointer as unsafe_Pointer
|
||||
participant "~*C.char" as c_char_ptr
|
||||
|
||||
== Go ==
|
||||
|
||||
int32 -> uintptr: int32 to uintptr
|
||||
uintptr -> unsafe_Pointer: uintptr to unsafe.Pointer
|
||||
|
||||
== CGO ==
|
||||
|
||||
unsafe_Pointer -> c_char_ptr: unsafe.Pointer to *C.char
|
||||
c_char_ptr -> unsafe_Pointer: ~*C.char to unsafe.Pointer
|
||||
|
||||
== Go ==
|
||||
|
||||
unsafe_Pointer -> uintptr: unsafe.Pointer to uintptr
|
||||
uintptr -> int32: uintptr to int32
|
||||
|
||||
@enduml
|
BIN
images/ch2-int32-to-char-ptr.uml.png
Normal file
After Width: | Height: | Size: 16 KiB |
88
images/ch2-qsort-v2.plantuml
Normal file
@ -0,0 +1,88 @@
|
||||
' Copyright 2017 <chaishushan{AT}gmail.com>. All rights reserved.
|
||||
' Use of this source code is governed by a Apache
|
||||
' license that can be found in the LICENSE file.
|
||||
|
||||
@startuml
|
||||
|
||||
title qsort
|
||||
|
||||
participant go
|
||||
participant c
|
||||
|
||||
[--> go: qsort
|
||||
activate go
|
||||
|
||||
go -> go
|
||||
activate go #DarkSalmon
|
||||
note left
|
||||
go_qsort_compare_info.elemsize = sv.Type().Elem().Size()
|
||||
go_qsort_compare_info.fn = fn
|
||||
end note
|
||||
|
||||
deactivate go
|
||||
|
||||
go -> c: C.qsort_proxy(cmp=go_qsort_compare)
|
||||
activate c
|
||||
note right
|
||||
void qsort_proxy(
|
||||
void* base, size_t num, size_t size,
|
||||
int (*compare)(const void* a, const void* b)
|
||||
) {
|
||||
go_qsort_compare_save_base(base);
|
||||
qsort(base, num, size, compare);
|
||||
}
|
||||
end note
|
||||
|
||||
' begin
|
||||
c -> c: C.go_qsort_compare_save_base
|
||||
activate c #DarkSalmon
|
||||
note right: callback go func
|
||||
|
||||
go <- c: go_qsort_compare_save_base
|
||||
activate go #DarkSalmon
|
||||
note left
|
||||
//export go_qsort_compare_save_base
|
||||
func go_qsort_compare_save_base(base unsafe.Pointer) {
|
||||
go_qsort_compare_info.base = uintptr(base)
|
||||
}
|
||||
var go_qsort_compare_info struct {
|
||||
base uintptr
|
||||
elemsize uintptr
|
||||
fn func(a, b int) int
|
||||
sync.RWMutex
|
||||
}
|
||||
end note
|
||||
|
||||
go -> c: go_qsort_compare_save_base done
|
||||
deactivate go
|
||||
|
||||
deactivate c
|
||||
' end
|
||||
|
||||
loop
|
||||
c -> c: C.go_qsort_compare
|
||||
activate c #DarkSalmon
|
||||
note right: callback go func
|
||||
|
||||
c -> go: go_qsort_compare
|
||||
activate go #DarkSalmon
|
||||
note left
|
||||
//export go_qsort_compare_save_base
|
||||
func go_qsort_compare_save_base(base unsafe.Pointer) {
|
||||
go_qsort_compare_info.base = uintptr(base)
|
||||
}
|
||||
end note
|
||||
|
||||
go -> c: go_qsort_compare done
|
||||
deactivate go
|
||||
|
||||
deactivate c
|
||||
end
|
||||
|
||||
go <- c: C.qsort_proxy done
|
||||
deactivate c
|
||||
|
||||
[<-- go: done
|
||||
deactivate go
|
||||
|
||||
@enduml
|
BIN
images/ch2-qsort-v2.uml.png
Normal file
After Width: | Height: | Size: 49 KiB |
23
images/ch2-x-ptr-to-y-ptr.plantuml
Normal file
@ -0,0 +1,23 @@
|
||||
' Copyright 2017 <chaishushan{AT}gmail.com>. All rights reserved.
|
||||
' Use of this source code is governed by a Apache
|
||||
' license that can be found in the LICENSE file.
|
||||
|
||||
@startuml
|
||||
|
||||
title *X <=> *Y
|
||||
|
||||
participant "~*X" as x_ptr
|
||||
participant unsafe.Pointer as unsafe_Pointer
|
||||
participant "~*Y" as y_ptr
|
||||
|
||||
== *X => *Y ==
|
||||
|
||||
x_ptr -> unsafe_Pointer: ~*X to unsafe.Pointer
|
||||
unsafe_Pointer -> y_ptr: unsafe.Pointer to *Y
|
||||
|
||||
== *Y => *X ==
|
||||
|
||||
y_ptr -> unsafe_Pointer: ~*Y to unsafe.Pointer
|
||||
unsafe_Pointer -> x_ptr: unsafe.Pointer to *X
|
||||
|
||||
@enduml
|
BIN
images/ch2-x-ptr-to-y-ptr.uml.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
36
images/ch2-x-slice-to-y-slice.plantuml
Normal file
@ -0,0 +1,36 @@
|
||||
' Copyright 2017 <chaishushan{AT}gmail.com>. All rights reserved.
|
||||
' Use of this source code is governed by a Apache
|
||||
' license that can be found in the LICENSE file.
|
||||
|
||||
|
||||
'var p []X
|
||||
'var q []Y // q = p
|
||||
|
||||
'pHdr := (*reflect.SliceHeader)(unsafe.Pointer(&p))
|
||||
'qHdr := (*reflect.SliceHeader)(unsafe.Pointer(&q))
|
||||
|
||||
'pHdr.Data = qHdr.Data
|
||||
'pHdr.Len = qHdr.Len * unsafe.Sizeof(q[0]) / unsafe.Sizeof(p[0])
|
||||
'pHdr.Cap = qHdr.Cap * unsafe.Sizeof(q[0]) / unsafe.Sizeof(p[0])
|
||||
|
||||
|
||||
@startuml
|
||||
|
||||
title []X <=> []Y
|
||||
|
||||
participant "var x []X\nvar y []Y" as slice
|
||||
participant "var px *SliceHeader\nvar py *SliceHeader" as slice_header
|
||||
|
||||
== []X and []Y to *reflect.SliceHeader ==
|
||||
|
||||
slice -> slice_header: px := (*reflect.SliceHeader)(unsafe.Pointer(&x))\npy := (*reflect.SliceHeader)(unsafe.Pointer(&y))
|
||||
|
||||
== copy *px to *py ==
|
||||
|
||||
slice_header -> slice_header: ~*py = *px
|
||||
|
||||
== y changed by *py ==
|
||||
|
||||
slice -> slice: y = x
|
||||
|
||||
@enduml
|
BIN
images/ch2-x-slice-to-y-slice.uml.png
Normal file
After Width: | Height: | Size: 14 KiB |