aid.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package al
  2. /*
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. */
  6. import "C"
  7. import "unsafe"
  8. import "runtime"
  9. import "fmt"
  10. // Helper functions for working with C easier
  11. // Calls C malloc
  12. func malloc(size int) unsafe.Pointer {
  13. return (unsafe.Pointer(C.calloc(C.size_t(size), C.size_t(1))))
  14. }
  15. // Calls C free
  16. func free(ptr unsafe.Pointer) {
  17. C.free(ptr)
  18. }
  19. // Allocates a string with the given byte length
  20. // don't forget a call to defer cstrFree() !
  21. func cstrNew(size int) *C.char {
  22. return (*C.char)(malloc((size)))
  23. }
  24. // free is a method on C char * strings to method to free the associated memory
  25. func cstrFree(self *C.char) {
  26. free(unsafe.Pointer(self))
  27. }
  28. // Coverts a string to a C string. This allocates memory,
  29. // so don't forget to add a "defer cstrFree(cstr)"
  30. func cstr(self string) *C.char {
  31. return C.CString(self)
  32. }
  33. // Shorthand for C.GoString. Yes, it's just laziness. :)
  34. func gostr(cstr *C.char) string {
  35. return C.GoString(cstr)
  36. }
  37. // Converts an int pointer to a C.int pointer.
  38. func cintptr(ptr *int) *C.int {
  39. return (*C.int)(unsafe.Pointer(ptr))
  40. }
  41. /*
  42. // Converts a byte pointer to a C.Uchar8 pointer.
  43. func cbyteptr(ptr * uint8) (*C.Uint8) {
  44. return (*C.Uint8)(unsafe.Pointer(ptr))
  45. }
  46. */
  47. // Converts ints to bools.
  48. func i2b(res int) bool {
  49. if res != 0 {
  50. return true
  51. }
  52. return false
  53. }
  54. // Converts bools to ints.
  55. func b2i(res bool) int {
  56. if res {
  57. return 1
  58. }
  59. return 0
  60. }
  61. // Interface for destructable objects
  62. type Destroyer interface {
  63. Destroy()
  64. }
  65. // Sets up a automatic finalizer for destructable objects
  66. // that will call Destroy using runtime.SetFinalizer
  67. // when the garbage collecter cleans up self.
  68. // self may also be nil in which case the destructor is NOT set up
  69. func SelfDestruct(self Destroyer) {
  70. if self == nil {
  71. return
  72. }
  73. clean := func(me Destroyer) {
  74. fmt.Printf("Finalizing %#v.\n", me)
  75. me.Destroy()
  76. }
  77. runtime.SetFinalizer(self, clean)
  78. }
  79. // this is too for laziness, but it's quite handy
  80. func cf(f float32) C.float {
  81. return C.float(f)
  82. }
  83. // this is too for laziness, but it's quite handy
  84. func ci(f int) C.int {
  85. return C.int(f)
  86. }
  87. // this is too for laziness, but it's quite handy
  88. func cd(f float64) C.double {
  89. return C.double(f)
  90. }
  91. // this is too for laziness, but it's quite handy
  92. func cui16(f int) C.uint16_t {
  93. return C.uint16_t(f)
  94. }
  95. //Converts an array of C strings to a slice of Go strings
  96. func GoStrings(argc C.int, argv **C.char) []string {
  97. length := int(argc)
  98. tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
  99. gostrings := make([]string, length)
  100. for i, s := range tmpslice {
  101. gostrings[i] = C.GoString(s)
  102. }
  103. return gostrings
  104. }
  105. //Converts an array of go strings to an array of C strings and a length
  106. func CStrings(args []string) (argc C.int, argv **C.char) {
  107. length := len(args)
  108. argv = (**C.char)(malloc(length * int(unsafe.Sizeof(*argv))))
  109. tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
  110. for i, s := range args {
  111. tmpslice[i] = cstr(s)
  112. }
  113. argc = C.int(length)
  114. return argc, argv
  115. }
  116. // frees the data allocated by Cstrings
  117. func CStringsFree(argc C.int, argv **C.char) {
  118. length := int(argc)
  119. tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
  120. for _, s := range tmpslice {
  121. cstrFree(s)
  122. }
  123. free(unsafe.Pointer(argv))
  124. }
  125. /* This is the usual boilerplate for wrapping C types through a handle
  126. type XXX struct {
  127. handle * C.YYY
  128. }
  129. // Converts a zzz to it's underlying C pointer
  130. func (self * XXX) toC() *C.YYY {
  131. return (*C.YYY)(self.handle)
  132. }
  133. // Destroys the zzz.
  134. func (self *XXX) Destroy() {
  135. if self.handle != nil {
  136. C.al_destroy_zzz(self.toC())
  137. }
  138. self.handle = nil
  139. }
  140. // Wraps a C zzz into a go zzz
  141. func wrapXXXRaw(data *C.YYY) *XXX {
  142. if data == nil {
  143. return nil
  144. }
  145. return &XXX{data}
  146. }
  147. // Sets up a finalizer for this XXX that calls Destroy()
  148. func (self *XXX) SetDestroyFinalizer() *XXX {
  149. if self != nil {
  150. runtime.SetFinalizer(self, func(me *XXX) { me.Destroy() })
  151. }
  152. return self
  153. }
  154. // Wraps a C zzz into a go zzz and sets up a finalizer that calls Destroy()
  155. func wrapXXX(data *C.YYY) *XXX {
  156. self := wrapXXXRaw(data)
  157. return self.SetDestroyFinalizer()
  158. }
  159. */