diff --git a/darwintest/newtypes.go b/darwintest/newtypes.go new file mode 100644 index 0000000..8fa0147 --- /dev/null +++ b/darwintest/newtypes.go @@ -0,0 +1,58 @@ +// 27 february 2014 +package main + +import ( + "fmt" + "unsafe" +) + +// #cgo CFLAGS: -Dqqq +// #cgo LDFLAGS: -lobjc -framework Foundation +// #include +// #include +// #include +// #include +// extern void ourMethod(id, SEL); +// /* cgo doesn't like Nil */ +// extern Class NilClass; /* in runtimetest.go because of cgo limitations */ +import "C" + +var NSObject = C.object_getClass(objc_getClass("NSObject")) + +func newClass(name string) C.Class { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + c := C.objc_allocateClassPair(NSObject, cname, 0) + if c == C.NilClass { + panic("unable to create Objective-C class " + name) + } + return c +} + +//export ourMethod +func ourMethod(self C.id, sel C.SEL) { + fmt.Println("hello, world") +} + +func addOurMethod(class C.Class, sel C.SEL) { + ty := []C.char{'v', '@', ':', 0} // according to the example for class_addMethod() + + // clas methods get stored in the metaclass; the objc_allocateClassPair() docs say this will work + metaclass := C.object_getClass(C.id(unsafe.Pointer(class))) + ok := C.class_addMethod(metaclass, + sel, + // using &C.ourMethod causes faults for some reason + C.IMP(unsafe.Pointer(C.ourMethod)), + &ty[0]) + if ok == C.BOOL(C.NO) { + panic("unable to add ourMethod") + } +} + +func mk(name string, sel C.SEL) C.id { + class := newClass(name) + addOurMethod(class, sel) + C.objc_registerClassPair(class) + return objc_getClass(name) +} diff --git a/darwintest/runtimetest.go b/darwintest/runtimetest.go index be6357f..f86398d 100644 --- a/darwintest/runtimetest.go +++ b/darwintest/runtimetest.go @@ -21,6 +21,7 @@ import ( // id objc_msgSend_strarg(id obj, SEL sel, char *a) { return objc_msgSend(obj, sel, a); } // id objc_msgSend_NSRect_uint_uint_bool(id obj, SEL sel, CGRect a, NSUInteger b, NSUInteger c, BOOL d) { return objc_msgSend(obj, sel, a, b, c, d); } // id objc_msgSend_id(id obj, SEL sel, id a) { return objc_msgSend(obj, sel, a); } +// Class NilClass = Nil; /* for newtypes.go */ import "C" func objc_getClass(class string) C.id { @@ -37,6 +38,12 @@ func sel_getUid(sel string) C.SEL { return C.sel_getUid(csel) } +func main() { + sel := sel_getUid("ourMethod") + C.objc_msgSend_noargs(mk("hello", sel), + sel) +} + const ( NSBorderlessWindowMask = 0 NSTitledWindowMask = 1 << 0 @@ -54,7 +61,7 @@ const ( var alloc = sel_getUid("alloc") -func main() { +func wintest() { NSWindow := objc_getClass("NSWindow") NSWindowinit := sel_getUid("initWithContentRect:styleMask:backing:defer:")