mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-24 04:16:01 +00:00
Merge branch 'master' of github.com:chai2010/advanced-go-programming-book
This commit is contained in:
commit
caef780949
4
.github/ISSUE_TEMPLATE.md
vendored
Normal file
4
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
## Expected Behavior
|
||||
|
||||
## Actual Behavior
|
||||
|
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
## Description
|
||||
|
||||
A few sentences describing the overall goals of the pull request's commits.
|
||||
|
||||
## Designs
|
||||
|
||||
If it's a feature, please write your code designs here.
|
||||
|
||||
## Notes to reviewers
|
||||
|
||||
Review the following things, including but not limit to:
|
||||
|
||||
1. Design
|
||||
2. Code (styles, magic...)
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -23,3 +23,9 @@ _obj
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
*.so
|
||||
*.dll
|
||||
*.obj
|
||||
*.o
|
||||
a.out
|
||||
|
10
SUMMARY.md
10
SUMMARY.md
@ -15,12 +15,16 @@
|
||||
* [2.3. CGO编程基础](ch2-cgo/ch2-03-basic.md)
|
||||
* [2.4. CGO内存模型](ch2-cgo/ch2-04-memory.md)
|
||||
* [2.5. C++类包装](ch2-cgo/ch2-05-class.md)
|
||||
* [2.6. 命令行工具和构建参数(TODO)](ch2-cgo/ch2-06-build.md)
|
||||
* [2.7. 静态库和动态库(TODO)](ch2-cgo/ch2-07-dll.md)
|
||||
* [2.8. 例子: 封装LevelDB(TODO)](ch2-cgo/ch2-08-leveldb.md)
|
||||
* [2.6. CGO包的可移植性(TODO)](ch2-cgo/ch2-06-go-get-friendly.md)
|
||||
* [2.7. Go实现Python模块(TODO)](ch2-cgo/ch2-07-py-module.md)
|
||||
* [2.8. SWIG(TODO)](ch2-cgo/ch2-08-swig.md)
|
||||
* [2.9. 补充说明(TODO)](ch2-cgo/ch2-09-faq.md)
|
||||
* [第三章 Go汇编语言](ch3-asm/readme.md)
|
||||
* [第四章 Go和脚本语言](ch4-xlang/readme.md)
|
||||
* [第六章 Go和Web](ch6-web/readme.md)
|
||||
* [6.1. Web开发简介](ch6-web/ch6-01-introduction.md)
|
||||
* [6.2. Router请求路由](ch6-web/ch6-02-router.md)
|
||||
* [6.3. Middleware中间件](ch6-web/ch6-03-middleware.md)
|
||||
* [附录](appendix/readme.md)
|
||||
* [附录A: Go语言常见坑](appendix/appendix-a-trap.md)
|
||||
* [附录B: 参考资料](appendix/appendix-b-ref.md)
|
||||
|
@ -61,17 +61,21 @@ import (
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var total int64
|
||||
var total uint64
|
||||
|
||||
func worker(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
for i := 0; i <= 100; i++ {
|
||||
var i uint64
|
||||
for i = 0; i <= 100; i++ {
|
||||
atomic.AddUint64(&total, i)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
|
||||
go worker(&wg)
|
||||
go worker(&wg)
|
||||
wg.Wait()
|
||||
|
@ -59,6 +59,39 @@ uint64_t | C.uint64_t | uint64
|
||||
|
||||
前文说过,如果C语言的类型是由多个关键字组成,无法通过虚拟的“C”包直接访问。比如C语言的`unsigned short`不能直接通过`C.unsigned short`访问。但是,在`<stdint.h>`中通过使用C语言的`typedef`关键字将`unsigned short`重新定义为`uint16_t`一个单词的类型后,我们就可以通过`C.uint16_t`访问原来的`unsigned short`类型了。对于比较复杂的C语言类型,推荐使用`typedef`关键字提高一个规则的类型命名,这样更利于在CGO中访问。
|
||||
|
||||
## Go 字符串和切片
|
||||
|
||||
在CGO生成的`_cgo_export.h`头文件中还会为Go语言特有的字符串、切片、字典、接口和管道等特有的数据类型生成对应的C语言类型:
|
||||
|
||||
```c
|
||||
typedef struct { const char *p; GoInt n; } GoString;
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
```
|
||||
|
||||
不过需要注意的是,其中只有Go语言的字符串和切片在CGO中有一定的使用价值,因为字符串和切片可以在Go调用C语言函数时马上使用。而其它的类型在C语言环境并无使用的价值,因为CGO并未针对这些类型提供相关的辅助函数,而且因为Go语言特有的内存模型的原因导致我们无法保持这些由Go语言管理的内存指针。
|
||||
|
||||
在导出的C语言函数中我们可以直接使用Go字符串和切片。假设有以下两个导出函数:
|
||||
|
||||
```go
|
||||
//export helloString
|
||||
func helloString(s string) {}
|
||||
|
||||
//export helloSlice
|
||||
func helloSlice(s []byte) {}
|
||||
```
|
||||
|
||||
CGO生成的`_cgo_export.h`头文件会包含以下的函数声明:
|
||||
|
||||
```c
|
||||
extern void helloString(GoString p0);
|
||||
extern void helloSlice(GoSlice p0);
|
||||
```
|
||||
|
||||
不过需要注意的是,如果使用了GoString类型会对`_cgo_export.h`头文件产生依赖,而这个头文件是动态输出的。更严谨的做法是为C语言函数接口定义严格的头文件,然后基于稳定的头文件实现代码。
|
||||
|
||||
## 结构体、联合、枚举类型
|
||||
|
||||
C语言的结构体、联合、枚举类型不能作为匿名成员被嵌入到Go语言的结构体中。在Go语言中,我们可以通过`C.struct_xxx`来访问C语言中定义的`struct xxx`结构体类型。结构体的内存布局按照C语言的通用对齐规则,在32位Go语言环境C语言结构体也按照32位对齐规则,在64位Go语言环境按照64位的对齐规则。对于指定了特殊对齐规则的结构体,无法在CGO中访问。
|
||||
|
@ -1,3 +0,0 @@
|
||||
# 2.6. 命令行工具和构建参数(TODO)
|
||||
|
||||
TODO
|
19
ch2-cgo/ch2-06-go-get-friendly.md
Normal file
19
ch2-cgo/ch2-06-go-get-friendly.md
Normal file
@ -0,0 +1,19 @@
|
||||
# 2.6. CGO包的可移植性(TODO)
|
||||
|
||||
TODO
|
||||
|
||||
<!--
|
||||
可移植的cgo
|
||||
|
||||
小的cgo包直接内置c/c++代码
|
||||
|
||||
1. copy到本目录
|
||||
|
||||
2. 创建 include 文件
|
||||
|
||||
很大的c包,全部内置会导致构建复杂化
|
||||
|
||||
分2步,1 go generate 进行构建
|
||||
2 lib 包含
|
||||
|
||||
-->
|
@ -1,4 +0,0 @@
|
||||
# 2.7 静态库和动态库(TODO)
|
||||
|
||||
TODO
|
||||
|
9
ch2-cgo/ch2-07-py-module.md
Normal file
9
ch2-cgo/ch2-07-py-module.md
Normal file
@ -0,0 +1,9 @@
|
||||
# 2.7 Go实现Python模块(TODO)
|
||||
|
||||
TODO
|
||||
|
||||
<!--
|
||||
静态库和动态库
|
||||
|
||||
实战: py 模块
|
||||
-->
|
@ -1,3 +0,0 @@
|
||||
# 2.8. 封装LevelDB(TODO)
|
||||
|
||||
TODO
|
7
ch2-cgo/ch2-08-swig.md
Normal file
7
ch2-cgo/ch2-08-swig.md
Normal file
@ -0,0 +1,7 @@
|
||||
# 2.8. SWIG(TODO)
|
||||
|
||||
TODO
|
||||
|
||||
<!--
|
||||
swig 简单说明
|
||||
-->
|
@ -1,3 +1,11 @@
|
||||
# 2.9. 补充说明(TODO)
|
||||
|
||||
TODO
|
||||
|
||||
<!--
|
||||
cgo的风险和不足
|
||||
|
||||
不要用c模拟Go字符串
|
||||
不要试图越过Go运行时的边界
|
||||
有些事情是不可为的,比如 bsearch 类似接口完全没有继承的价值(代价太高)
|
||||
-->
|
||||
|
3
ch3-asm/readme.md
Normal file
3
ch3-asm/readme.md
Normal file
@ -0,0 +1,3 @@
|
||||
# 第三章 Go汇编语言
|
||||
|
||||
TODO
|
3
ch4-xlang/readme.md
Normal file
3
ch4-xlang/readme.md
Normal file
@ -0,0 +1,3 @@
|
||||
# 第四章 Go和脚本语言
|
||||
|
||||
TODO
|
12
examples/ch2-07/hello-py/Makefile
Normal file
12
examples/ch2-07/hello-py/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
default:
|
||||
go build -buildmode=c-shared -o gopkg.so main.go
|
||||
python3 -c 'import gopkg; print(gopkg.system("time"))'
|
||||
python3 -c 'import gopkg; print(gopkg.sum(2, 3))'
|
||||
|
||||
clean:
|
||||
-rm *.so
|
||||
|
||||
# PKG_CONFIG=python3-config go build -buildmode=c-shared -o say-hello.so main.go
|
||||
# python3-config --ldflags
|
||||
# python3-config --include
|
||||
|
106
examples/ch2-07/hello-py/gopkg.h
Normal file
106
examples/ch2-07/hello-py/gopkg.h
Normal file
@ -0,0 +1,106 @@
|
||||
/* Created by "go tool cgo" - DO NOT EDIT. */
|
||||
|
||||
/* package command-line-arguments */
|
||||
|
||||
/* Start of preamble from import "C" comments. */
|
||||
|
||||
|
||||
#line 3 "/Users/chai/go/src/github.com/chai2010/advanced-go-programming-book/examples/ch2-07/hello-py/main.go"
|
||||
|
||||
// macOS:
|
||||
// python3-config --cflags
|
||||
// python3-config --ldflags
|
||||
|
||||
|
||||
|
||||
// linux
|
||||
|
||||
|
||||
// windows
|
||||
// should generate libpython3.a from python3.lib
|
||||
|
||||
#define Py_LIMITED_API
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject *
|
||||
spam_system(PyObject *self, PyObject *args) {
|
||||
const char *command;
|
||||
if (!PyArg_ParseTuple(args, "s", &command)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int status = system(command);
|
||||
return PyLong_FromLong(status);
|
||||
}
|
||||
|
||||
extern PyObject *sum(PyObject *self, PyObject *args);
|
||||
|
||||
static PyMethodDef modMethods[] = {
|
||||
{"system", spam_system, METH_VARARGS, "Execute a shell command."},
|
||||
{"sum", sum, METH_VARARGS, "Execute a shell command."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static PyObject* PyInit_gopkg_(void) {
|
||||
static struct PyModuleDef module = {
|
||||
PyModuleDef_HEAD_INIT, "gopkg", NULL, -1, modMethods,
|
||||
};
|
||||
return (void*)PyModule_Create(&module);
|
||||
}
|
||||
|
||||
#line 1 "cgo-generated-wrapper"
|
||||
|
||||
|
||||
/* 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];
|
||||
|
||||
typedef struct { const char *p; GoInt n; } GoString;
|
||||
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 PyObject* sum(PyObject* p0, PyObject* p1);
|
||||
|
||||
extern PyObject* PyInit_gopkg();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
66
examples/ch2-07/hello-py/main.go
Normal file
66
examples/ch2-07/hello-py/main.go
Normal file
@ -0,0 +1,66 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
// macOS:
|
||||
// python3-config --cflags
|
||||
// python3-config --ldflags
|
||||
#cgo darwin CFLAGS: -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -fno-strict-aliasing -Wsign-compare -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -g
|
||||
#cgo darwin LDFLAGS: -L/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/config-3.6m-darwin -lpython3.6m -ldl -framework CoreFoundation
|
||||
|
||||
// linux
|
||||
#cgo linux pkg-config: python3
|
||||
|
||||
// windows
|
||||
// should generate libpython3.a from python3.lib
|
||||
|
||||
#define Py_LIMITED_API
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject *
|
||||
spam_system(PyObject *self, PyObject *args) {
|
||||
const char *command;
|
||||
if (!PyArg_ParseTuple(args, "s", &command)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int status = system(command);
|
||||
return PyLong_FromLong(status);
|
||||
}
|
||||
|
||||
extern PyObject *sum(PyObject *self, PyObject *args);
|
||||
|
||||
static PyMethodDef modMethods[] = {
|
||||
{"system", spam_system, METH_VARARGS, "Execute a shell command."},
|
||||
{"sum", sum, METH_VARARGS, "Execute a shell command."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static PyObject* PyInit_gopkg_(void) {
|
||||
static struct PyModuleDef module = {
|
||||
PyModuleDef_HEAD_INIT, "gopkg", NULL, -1, modMethods,
|
||||
};
|
||||
return (void*)PyModule_Create(&module);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {}
|
||||
|
||||
// export SayHello
|
||||
func SayHello(name *C.char) {
|
||||
fmt.Printf("hello %s!\n", C.GoString(name))
|
||||
}
|
||||
|
||||
//export sum
|
||||
func sum(self, args *C.PyObject) *C.PyObject {
|
||||
return C.PyLong_FromLongLong(9527) // TODO
|
||||
}
|
||||
|
||||
//export PyInit_gopkg
|
||||
func PyInit_gopkg() *C.PyObject {
|
||||
return C.PyInit_gopkg_()
|
||||
}
|
11
examples/ch2-07/hello-so/Makefile
Normal file
11
examples/ch2-07/hello-so/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
default:
|
||||
go build -buildmode=c-shared -o say-hello.so main.go
|
||||
gcc -Wall _test_so.c ./say-hello.so
|
||||
./a.out
|
||||
|
||||
run-py3:
|
||||
python3 hello.py
|
||||
|
||||
clean:
|
||||
-rm *.so
|
||||
-rm *.out
|
7
examples/ch2-07/hello-so/_test_so.c
Normal file
7
examples/ch2-07/hello-so/_test_so.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "say-hello.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
SayHello("gopher");
|
||||
return 0;
|
||||
}
|
9
examples/ch2-07/hello-so/hello.py
Normal file
9
examples/ch2-07/hello-so/hello.py
Normal file
@ -0,0 +1,9 @@
|
||||
from ctypes import *
|
||||
|
||||
libso = CDLL("./say-hello.so")
|
||||
|
||||
SayHello = libso.SayHello
|
||||
SayHello.argtypes = [c_char_p]
|
||||
SayHello.restype = None
|
||||
|
||||
SayHello(c_char_p(b"hello"))
|
11
examples/ch2-07/hello-so/main.go
Normal file
11
examples/ch2-07/hello-so/main.go
Normal file
@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "C"
|
||||
import "fmt"
|
||||
|
||||
func main() {}
|
||||
|
||||
//export SayHello
|
||||
func SayHello(name *C.char) {
|
||||
fmt.Printf("hello %s!\n", C.GoString(name))
|
||||
}
|
60
examples/ch2-07/hello-so/say-hello.h
Normal file
60
examples/ch2-07/hello-so/say-hello.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* Created by "go tool cgo" - DO NOT EDIT. */
|
||||
|
||||
/* package command-line-arguments */
|
||||
|
||||
/* 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];
|
||||
|
||||
typedef struct { const char *p; GoInt n; } GoString;
|
||||
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 void SayHello(char* p0);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
1
examples/ch2-xx/hello/.gitignore
vendored
Normal file
1
examples/ch2-xx/hello/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
!/_obj
|
2
examples/ch2-xx/hello/Makefile
Normal file
2
examples/ch2-xx/hello/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
default:
|
||||
go tool cgo hello.go
|
58
examples/ch2-xx/hello/_obj/_cgo_export.c
Normal file
58
examples/ch2-xx/hello/_obj/_cgo_export.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* Created by cgo - DO NOT EDIT. */
|
||||
#include <stdlib.h>
|
||||
#include "_cgo_export.h"
|
||||
|
||||
extern void crosscall2(void (*fn)(void *, int, __SIZE_TYPE__), void *, int, __SIZE_TYPE__);
|
||||
extern __SIZE_TYPE__ _cgo_wait_runtime_init_done();
|
||||
extern void _cgo_release_context(__SIZE_TYPE__);
|
||||
|
||||
extern char* _cgo_topofstack(void);
|
||||
#define CGO_NO_SANITIZE_THREAD
|
||||
#define _cgo_tsan_acquire()
|
||||
#define _cgo_tsan_release()
|
||||
|
||||
extern void _cgoexp_16f1900c27a8_helloInt(void *, int, __SIZE_TYPE__);
|
||||
|
||||
CGO_NO_SANITIZE_THREAD
|
||||
void helloInt(GoInt p0)
|
||||
{
|
||||
__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();
|
||||
struct {
|
||||
GoInt p0;
|
||||
} __attribute__((__packed__)) a;
|
||||
a.p0 = p0;
|
||||
_cgo_tsan_release();
|
||||
crosscall2(_cgoexp_16f1900c27a8_helloInt, &a, 8, _cgo_ctxt);
|
||||
_cgo_tsan_acquire();
|
||||
_cgo_release_context(_cgo_ctxt);
|
||||
}
|
||||
extern void _cgoexp_16f1900c27a8_helloString(void *, int, __SIZE_TYPE__);
|
||||
|
||||
CGO_NO_SANITIZE_THREAD
|
||||
void helloString(GoString p0)
|
||||
{
|
||||
__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();
|
||||
struct {
|
||||
GoString p0;
|
||||
} __attribute__((__packed__)) a;
|
||||
a.p0 = p0;
|
||||
_cgo_tsan_release();
|
||||
crosscall2(_cgoexp_16f1900c27a8_helloString, &a, 16, _cgo_ctxt);
|
||||
_cgo_tsan_acquire();
|
||||
_cgo_release_context(_cgo_ctxt);
|
||||
}
|
||||
extern void _cgoexp_16f1900c27a8_helloSlice(void *, int, __SIZE_TYPE__);
|
||||
|
||||
CGO_NO_SANITIZE_THREAD
|
||||
void helloSlice(GoSlice p0)
|
||||
{
|
||||
__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();
|
||||
struct {
|
||||
GoSlice p0;
|
||||
} __attribute__((__packed__)) a;
|
||||
a.p0 = p0;
|
||||
_cgo_tsan_release();
|
||||
crosscall2(_cgoexp_16f1900c27a8_helloSlice, &a, 24, _cgo_ctxt);
|
||||
_cgo_tsan_acquire();
|
||||
_cgo_release_context(_cgo_ctxt);
|
||||
}
|
64
examples/ch2-xx/hello/_obj/_cgo_export.h
Normal file
64
examples/ch2-xx/hello/_obj/_cgo_export.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* Created by "go tool cgo" - DO NOT EDIT. */
|
||||
|
||||
/* package main */
|
||||
|
||||
/* 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];
|
||||
|
||||
typedef struct { const char *p; GoInt n; } GoString;
|
||||
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 void helloInt(GoInt p0);
|
||||
|
||||
extern void helloString(GoString p0);
|
||||
|
||||
extern void helloSlice(GoSlice p0);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
1
examples/ch2-xx/hello/_obj/_cgo_flags
Normal file
1
examples/ch2-xx/hello/_obj/_cgo_flags
Normal file
@ -0,0 +1 @@
|
||||
_CGO_CFLAGS=
|
70
examples/ch2-xx/hello/_obj/_cgo_gotypes.go
Normal file
70
examples/ch2-xx/hello/_obj/_cgo_gotypes.go
Normal file
@ -0,0 +1,70 @@
|
||||
// Created by cgo - DO NOT EDIT
|
||||
|
||||
package main
|
||||
|
||||
import "unsafe"
|
||||
|
||||
import _ "runtime/cgo"
|
||||
|
||||
import "syscall"
|
||||
|
||||
var _ syscall.Errno
|
||||
func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }
|
||||
|
||||
//go:linkname _Cgo_always_false runtime.cgoAlwaysFalse
|
||||
var _Cgo_always_false bool
|
||||
//go:linkname _Cgo_use runtime.cgoUse
|
||||
func _Cgo_use(interface{})
|
||||
type _Ctype_void [0]byte
|
||||
|
||||
//go:linkname _cgo_runtime_cgocall runtime.cgocall
|
||||
func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
|
||||
|
||||
//go:linkname _cgo_runtime_cgocallback runtime.cgocallback
|
||||
func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr)
|
||||
|
||||
//go:linkname _cgoCheckPointer runtime.cgoCheckPointer
|
||||
func _cgoCheckPointer(interface{}, ...interface{})
|
||||
|
||||
//go:linkname _cgoCheckResult runtime.cgoCheckResult
|
||||
func _cgoCheckResult(interface{})
|
||||
|
||||
//go:cgo_export_dynamic helloInt
|
||||
//go:linkname _cgoexp_16f1900c27a8_helloInt _cgoexp_16f1900c27a8_helloInt
|
||||
//go:cgo_export_static _cgoexp_16f1900c27a8_helloInt
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgoexp_16f1900c27a8_helloInt(a unsafe.Pointer, n int32, ctxt uintptr) {
|
||||
fn := _cgoexpwrap_16f1900c27a8_helloInt
|
||||
_cgo_runtime_cgocallback(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), a, uintptr(n), ctxt);
|
||||
}
|
||||
|
||||
func _cgoexpwrap_16f1900c27a8_helloInt(p0 int) {
|
||||
helloInt(p0)
|
||||
}
|
||||
//go:cgo_export_dynamic helloString
|
||||
//go:linkname _cgoexp_16f1900c27a8_helloString _cgoexp_16f1900c27a8_helloString
|
||||
//go:cgo_export_static _cgoexp_16f1900c27a8_helloString
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgoexp_16f1900c27a8_helloString(a unsafe.Pointer, n int32, ctxt uintptr) {
|
||||
fn := _cgoexpwrap_16f1900c27a8_helloString
|
||||
_cgo_runtime_cgocallback(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), a, uintptr(n), ctxt);
|
||||
}
|
||||
|
||||
func _cgoexpwrap_16f1900c27a8_helloString(p0 string) {
|
||||
helloString(p0)
|
||||
}
|
||||
//go:cgo_export_dynamic helloSlice
|
||||
//go:linkname _cgoexp_16f1900c27a8_helloSlice _cgoexp_16f1900c27a8_helloSlice
|
||||
//go:cgo_export_static _cgoexp_16f1900c27a8_helloSlice
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgoexp_16f1900c27a8_helloSlice(a unsafe.Pointer, n int32, ctxt uintptr) {
|
||||
fn := _cgoexpwrap_16f1900c27a8_helloSlice
|
||||
_cgo_runtime_cgocallback(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), a, uintptr(n), ctxt);
|
||||
}
|
||||
|
||||
func _cgoexpwrap_16f1900c27a8_helloSlice(p0 []byte) {
|
||||
helloSlice(p0)
|
||||
}
|
12
examples/ch2-xx/hello/_obj/_cgo_main.c
Normal file
12
examples/ch2-xx/hello/_obj/_cgo_main.c
Normal file
@ -0,0 +1,12 @@
|
||||
int main() { return 0; }
|
||||
void crosscall2(void(*fn)(void*, int, __SIZE_TYPE__), void *a, int c, __SIZE_TYPE__ ctxt) { }
|
||||
__SIZE_TYPE__ _cgo_wait_runtime_init_done() { return 0; }
|
||||
void _cgo_release_context(__SIZE_TYPE__ ctxt) { }
|
||||
char* _cgo_topofstack(void) { return (char*)0; }
|
||||
void _cgo_allocate(void *a, int c) { }
|
||||
void _cgo_panic(void *a, int c) { }
|
||||
void _cgo_reginit(void) { }
|
||||
#line 1 "cgo-generated-wrappers"
|
||||
int _cgoexp_16f1900c27a8_helloInt;
|
||||
int _cgoexp_16f1900c27a8_helloString;
|
||||
int _cgoexp_16f1900c27a8_helloSlice;
|
24
examples/ch2-xx/hello/_obj/hello.cgo1.go
Normal file
24
examples/ch2-xx/hello/_obj/hello.cgo1.go
Normal file
@ -0,0 +1,24 @@
|
||||
// Created by cgo - DO NOT EDIT
|
||||
|
||||
//line /Users/chai/go/src/github.com/chai2010/advanced-go-programming-book/examples/ch2-xx/hello/hello.go:1
|
||||
package main
|
||||
|
||||
//line /Users/chai/go/src/github.com/chai2010/advanced-go-programming-book/examples/ch2-xx/hello/hello.go:5
|
||||
func main() {
|
||||
helloString("hello")
|
||||
}
|
||||
|
||||
//line /Users/chai/go/src/github.com/chai2010/advanced-go-programming-book/examples/ch2-xx/hello/hello.go:10
|
||||
func helloInt(s int) {
|
||||
println(s)
|
||||
}
|
||||
|
||||
//line /Users/chai/go/src/github.com/chai2010/advanced-go-programming-book/examples/ch2-xx/hello/hello.go:15
|
||||
func helloString(s string) {
|
||||
println(s)
|
||||
}
|
||||
|
||||
//line /Users/chai/go/src/github.com/chai2010/advanced-go-programming-book/examples/ch2-xx/hello/hello.go:20
|
||||
func helloSlice(s []byte) {
|
||||
println(string(s))
|
||||
}
|
31
examples/ch2-xx/hello/_obj/hello.cgo2.c
Normal file
31
examples/ch2-xx/hello/_obj/hello.cgo2.c
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
|
||||
#line 1 "cgo-gcc-prolog"
|
||||
/*
|
||||
If x and y are not equal, the type will be invalid
|
||||
(have a negative array count) and an inscrutable error will come
|
||||
out of the compiler and hopefully mention "name".
|
||||
*/
|
||||
#define __cgo_compile_assert_eq(x, y, name) typedef char name[(x-y)*(x-y)*-2+1];
|
||||
|
||||
/* Check at compile time that the sizes we use match our expectations. */
|
||||
#define __cgo_size_assert(t, n) __cgo_compile_assert_eq(sizeof(t), n, _cgo_sizeof_##t##_is_not_##n)
|
||||
|
||||
__cgo_size_assert(char, 1)
|
||||
__cgo_size_assert(short, 2)
|
||||
__cgo_size_assert(int, 4)
|
||||
typedef long long __cgo_long_long;
|
||||
__cgo_size_assert(__cgo_long_long, 8)
|
||||
__cgo_size_assert(float, 4)
|
||||
__cgo_size_assert(double, 8)
|
||||
|
||||
extern char* _cgo_topofstack(void);
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define CGO_NO_SANITIZE_THREAD
|
||||
#define _cgo_tsan_acquire()
|
||||
#define _cgo_tsan_release()
|
||||
|
22
examples/ch2-xx/hello/hello.go
Normal file
22
examples/ch2-xx/hello/hello.go
Normal file
@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import "C"
|
||||
|
||||
func main() {
|
||||
helloString("hello") // _GoString_
|
||||
}
|
||||
|
||||
//export helloInt
|
||||
func helloInt(s int) {
|
||||
println(s)
|
||||
}
|
||||
|
||||
//export helloString
|
||||
func helloString(s string) {
|
||||
println(s)
|
||||
}
|
||||
|
||||
//export helloSlice
|
||||
func helloSlice(s []byte) {
|
||||
println(string(s))
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user