mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-24 20:52:22 +00:00
ch2-05: 增加Go对象到C++对象例子
This commit is contained in:
parent
be10ffdd88
commit
cbe21e4cbc
53
examples/ch2-05/class-go2cc/goobj.go
Normal file
53
examples/ch2-05/class-go2cc/goobj.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ObjectId int32
|
||||||
|
|
||||||
|
var refs struct {
|
||||||
|
sync.Mutex
|
||||||
|
objs map[ObjectId]interface{}
|
||||||
|
next ObjectId
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
refs.Lock()
|
||||||
|
defer refs.Unlock()
|
||||||
|
|
||||||
|
refs.objs = make(map[ObjectId]interface{})
|
||||||
|
refs.next = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewObjectId(obj interface{}) ObjectId {
|
||||||
|
refs.Lock()
|
||||||
|
defer refs.Unlock()
|
||||||
|
|
||||||
|
id := refs.next
|
||||||
|
refs.next++
|
||||||
|
|
||||||
|
refs.objs[id] = obj
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (id ObjectId) IsNil() bool {
|
||||||
|
return id == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (id ObjectId) Get() interface{} {
|
||||||
|
refs.Lock()
|
||||||
|
defer refs.Unlock()
|
||||||
|
|
||||||
|
return refs.objs[id]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (id ObjectId) Free() interface{} {
|
||||||
|
refs.Lock()
|
||||||
|
defer refs.Unlock()
|
||||||
|
|
||||||
|
obj := refs.objs[id]
|
||||||
|
delete(refs.objs, id)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
}
|
14
examples/ch2-05/class-go2cc/main.cc
Normal file
14
examples/ch2-05/class-go2cc/main.cc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "person.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern "C" void Main() {
|
||||||
|
auto p = Person::New("gopher", 10);
|
||||||
|
|
||||||
|
char buf[64];
|
||||||
|
char* name = p->GetName(buf, sizeof(buf)-1);
|
||||||
|
int age = p->GetAge();
|
||||||
|
|
||||||
|
printf("%s, %d years old.\n", name, age);
|
||||||
|
p->Delete();
|
||||||
|
}
|
9
examples/ch2-05/class-go2cc/main.go
Normal file
9
examples/ch2-05/class-go2cc/main.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// #cgo CXXFLAGS: -std=c++11
|
||||||
|
// extern void Main();
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
C.Main()
|
||||||
|
}
|
22
examples/ch2-05/class-go2cc/persion.go
Normal file
22
examples/ch2-05/class-go2cc/persion.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPerson(name string, age int) *Person {
|
||||||
|
return &Person{
|
||||||
|
name: name,
|
||||||
|
age: age,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Person) Set(name string, age int) {
|
||||||
|
p.name = name
|
||||||
|
p.age = age
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Person) Get() (name string, age int) {
|
||||||
|
return p.name, p.age
|
||||||
|
}
|
1
examples/ch2-05/class-go2cc/person.cc
Normal file
1
examples/ch2-05/class-go2cc/person.cc
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "person.h"
|
23
examples/ch2-05/class-go2cc/person.h
Normal file
23
examples/ch2-05/class-go2cc/person.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "./person_capi.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Person {
|
||||||
|
static Person* New(const char* name, int age) {
|
||||||
|
return (Person*)person_new((char*)name, age);
|
||||||
|
}
|
||||||
|
void Delete() {
|
||||||
|
person_delete(person_handle_t(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(char* name, int age) {
|
||||||
|
person_set(person_handle_t(this), name, age);
|
||||||
|
}
|
||||||
|
char* GetName(char* buf, int size) {
|
||||||
|
return person_get_name(person_handle_t(this), buf, size);
|
||||||
|
}
|
||||||
|
int GetAge() {
|
||||||
|
return person_get_age(person_handle_t(this));
|
||||||
|
}
|
||||||
|
};
|
42
examples/ch2-05/class-go2cc/person_capi.go
Normal file
42
examples/ch2-05/class-go2cc/person_capi.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
//#include "./person_capi.h"
|
||||||
|
import "C"
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
//export person_new
|
||||||
|
func person_new(name *C.char, age C.int) C.person_handle_t {
|
||||||
|
id := NewObjectId(NewPerson(C.GoString(name), int(age)))
|
||||||
|
return C.person_handle_t(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export person_delete
|
||||||
|
func person_delete(h C.person_handle_t) {
|
||||||
|
ObjectId(h).Free()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export person_set
|
||||||
|
func person_set(h C.person_handle_t, name *C.char, age C.int) {
|
||||||
|
p := ObjectId(h).Get().(*Person)
|
||||||
|
p.Set(C.GoString(name), int(age))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export person_get_name
|
||||||
|
func person_get_name(h C.person_handle_t, buf *C.char, size C.int) *C.char {
|
||||||
|
p := ObjectId(h).Get().(*Person)
|
||||||
|
name, _ := p.Get()
|
||||||
|
|
||||||
|
n := int(size) - 1
|
||||||
|
bufSlice := ((*[1 << 31]byte)(unsafe.Pointer(buf)))[0:n:n]
|
||||||
|
n = copy(bufSlice, []byte(name))
|
||||||
|
bufSlice[n] = 0
|
||||||
|
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
//export person_get_age
|
||||||
|
func person_get_age(h C.person_handle_t) C.int {
|
||||||
|
p := ObjectId(h).Get().(*Person)
|
||||||
|
_, age := p.Get()
|
||||||
|
return C.int(age)
|
||||||
|
}
|
10
examples/ch2-05/class-go2cc/person_capi.h
Normal file
10
examples/ch2-05/class-go2cc/person_capi.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef uintptr_t person_handle_t;
|
||||||
|
|
||||||
|
person_handle_t person_new(char* name, int age);
|
||||||
|
void person_delete(person_handle_t p);
|
||||||
|
|
||||||
|
void person_set(person_handle_t p, char* name, int age);
|
||||||
|
char* person_get_name(person_handle_t p, char* buf, int size);
|
||||||
|
int person_get_age(person_handle_t p);
|
Loading…
x
Reference in New Issue
Block a user