aid.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. // Sometimes I need many floats..
  92. func cf2(f1, f2 float32) (C.float, C.float) {
  93. return C.float(f1), C.float(f2)
  94. }
  95. // Sometimes I need many floats..
  96. func cf3(f1, f2, f3 float32) (C.float, C.float, C.float) {
  97. return C.float(f1), C.float(f2), C.float(f3)
  98. }
  99. // this is too for laziness, but it's quite handy
  100. func cui16(f int) C.uint16_t {
  101. return C.uint16_t(f)
  102. }
  103. //Converts an array of C strings to a slice of Go strings
  104. func GoStrings(argc C.int, argv **C.char) []string {
  105. length := int(argc)
  106. tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
  107. gostrings := make([]string, length)
  108. for i, s := range tmpslice {
  109. gostrings[i] = C.GoString(s)
  110. }
  111. return gostrings
  112. }
  113. //Converts an array of go strings to an array of C strings and a length
  114. func CStrings(args []string) (argc C.int, argv **C.char) {
  115. length := len(args)
  116. argv = (**C.char)(malloc(length * int(unsafe.Sizeof(*argv))))
  117. tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
  118. for i, s := range args {
  119. tmpslice[i] = cstr(s)
  120. }
  121. argc = C.int(length)
  122. return argc, argv
  123. }
  124. // frees the data allocated by Cstrings
  125. func CStringsFree(argc C.int, argv **C.char) {
  126. length := int(argc)
  127. tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
  128. for _, s := range tmpslice {
  129. cstrFree(s)
  130. }
  131. free(unsafe.Pointer(argv))
  132. }
  133. //Converts an array of go ints to an array of C ints and a length
  134. func CInts(args []int) (argc C.int, argv *C.int) {
  135. length := len(args)
  136. argv = (*C.int)(malloc(length * int(unsafe.Sizeof(argv))))
  137. tmpslice := (*[1 << 30]C.int)(unsafe.Pointer(argv))[:length:length]
  138. for i, v := range args {
  139. tmpslice[i] = C.int(v)
  140. }
  141. argc = C.int(length)
  142. return argc, argv
  143. }
  144. // frees the data allocated by Cints
  145. func CIntsFree(argc C.int, argv *C.int) {
  146. free(unsafe.Pointer(argv))
  147. }
  148. //Converts an array of go float32 to an array of C float and a length
  149. func CFloats(args []float32) (argc C.int, argv *C.float) {
  150. length := len(args)
  151. argv = (*C.float)(malloc(length * int(unsafe.Sizeof(*argv))))
  152. tmpslice := (*[1 << 30]C.float)(unsafe.Pointer(argv))[:length:length]
  153. for i, v := range args {
  154. tmpslice[i] = C.float(v)
  155. }
  156. argc = C.int(length)
  157. return argc, argv
  158. }
  159. // frees the data allocated by Cints
  160. func CFloatsFree(argc C.int, argv *C.float) {
  161. free(unsafe.Pointer(argv))
  162. }
  163. /* This is the usual boilerplate for wrapping C types through a handle
  164. type XXX struct {
  165. handle * C.YYY
  166. }
  167. // Converts a zzz to it's underlying C pointer
  168. func (self * XXX) toC() *C.YYY {
  169. return (*C.YYY)(self.handle)
  170. }
  171. // Destroys the zzz.
  172. func (self *XXX) Destroy() {
  173. if self.handle != nil {
  174. C.al_destroy_zzz(self.toC())
  175. }
  176. self.handle = nil
  177. }
  178. // Wraps a C zzz into a go zzz
  179. func wrapXXXRaw(data *C.YYY) *XXX {
  180. if data == nil {
  181. return nil
  182. }
  183. return &XXX{data}
  184. }
  185. // Sets up a finalizer for this XXX that calls Destroy()
  186. func (self *XXX) SetDestroyFinalizer() *XXX {
  187. if self != nil {
  188. runtime.SetFinalizer(self, func(me *XXX) { me.Destroy() })
  189. }
  190. return self
  191. }
  192. // Wraps a C zzz into a go zzz and sets up a finalizer that calls Destroy()
  193. func wrapXXX(data *C.YYY) *XXX {
  194. self := wrapXXXRaw(data)
  195. return self.SetDestroyFinalizer()
  196. }
  197. */