Я следовал учебному пособию по вызову объективного кода c из golang. Учебное пособие находится по этой ссылке
Код выглядит следующим образом (он аналогичен учебному пособию)
main. go
package main
import (
"fmt"
"net/url"
"strconv"
"unsafe"
)
//#cgo CFLAGS: -x objective-c
//#cgo LDFLAGS: -framework Foundation
//#include "foundation.h"
import "C"
// NSString -> C string
func cstring(s *C.NSString) *C.char { return C.nsstring2cstring(s) }
// NSString -> Go string
func gostring(s *C.NSString) string { return C.GoString(cstring(s)) }
// NSNumber -> Go int
func goint(i *C.NSNumber) int { return int(C.nsnumber2int(i)) }
// NSArray length
func nsarraylen(arr *C.NSArray) uint { return uint(C.nsarraylen(arr)) }
// NSArray item
func nsarrayitem(arr *C.NSArray, i uint) unsafe.Pointer {
return C.nsarrayitem(arr, C.ulong(i))
}
// NSURL -> Go url.URL
func gourl(nsurlptr *C.NSURL) *url.URL {
nsurl := *C.nsurldata(nsurlptr)
userInfo := url.UserPassword(
gostring(nsurl.user),
gostring(nsurl.password),
)
host := gostring(nsurl.host)
if nsurl.port != nil {
port := goint(nsurl.port)
host = host + ":" + strconv.FormatInt(int64(port), 10)
}
return &url.URL{
Scheme: gostring(nsurl.scheme),
User: userInfo, // username and password information
Host: host, // host or host:port
Path: gostring(nsurl.path),
RawQuery: gostring(nsurl.query), // encoded query values, without '?'
Fragment: gostring(nsurl.fragment), // fragment for references, without '#'
}
}
// NSArray<NSURL> -> Go []url.URL
func gourls(arr *C.NSArray) []url.URL {
var result []url.URL
length := nsarraylen(arr)
for i := uint(0); i < length; i++ {
nsurl := (*C.NSURL)(nsarrayitem(arr, i))
u := gourl(nsurl)
result = append(result, *u)
}
return result
}
func UserApplicationSupportDirectories() []url.URL {
return gourls(C.UserApplicationSupportDirectories())
}
func main() {
fmt.Printf("%#+v\n", UserApplicationSupportDirectories())
}
Foundation.h
#import <Foundation/Foundation.h>
typedef struct _NSURLdata {
NSString *scheme;
NSString *user;
NSString *password;
NSString *host;
NSNumber *port;
NSString *path;
NSString *query;
NSString *fragment;
} NSURLdata;
const char* nsstring2cstring(NSString*);
int nsnumber2int(NSNumber*);
unsigned long nsarraylen(NSArray*);
const void* nsarrayitem(NSArray*, unsigned long);
const NSURLdata* nsurldata(NSURL*);
const NSArray* UserApplicationSupportDirectories();
Foundation.m
#import "foundation.h"
const char*
nsstring2cstring(NSString *s) {
if (s == NULL) { return NULL; }
const char *cstr = [s UTF8String];
return cstr;
}
int
nsnumber2int(NSNumber *i) {
if (i == NULL) { return 0; }
return i.intValue;
}
unsigned long
nsarraylen(NSArray *arr) {
if (arr == NULL) { return 0; }
return arr.count;
}
const void*
nsarrayitem(NSArray *arr, unsigned long i) {
if (arr == NULL) { return NULL; }
return [arr objectAtIndex:i];
}
const NSURLdata*
nsurldata(NSURL *url) {
NSURLdata *urldata = malloc(sizeof(NSURLdata));
urldata->scheme = url.scheme;
urldata->user = url.user;
urldata->password = url.password;
urldata->host = url.host;
urldata->port = url.port;
urldata->path = url.path;
urldata->query = url.query;
urldata->fragment = url.fragment;
return urldata;
}
const NSArray*
UserApplicationSupportDirectories() {
NSFileManager *manager = [NSFileManager defaultManager];
return [manager URLsForDirectory: NSApplicationSupportDirectory
inDomains: NSUserDomainMask];
}
Когда я создаю этот код, я получаю следующие предупреждения от компилятора
cgo-gcc-prolog:70:47: warning: incompatible pointer types passing 'struct NSArray *' to parameter of type 'NSArray *' [-Wincompatible-pointer-types]
./foundation.h:17:33: note: passing argument to parameter here
cgo-gcc-prolog:88:22: warning: incompatible pointer types passing 'struct NSArray *' to parameter of type 'NSArray *' [-Wincompatible-pointer-types]
./foundation.h:16:34: note: passing argument to parameter here
cgo-gcc-prolog:107:24: warning: incompatible pointer types passing 'struct NSNumber *' to parameter of type 'NSNumber *' [-Wincompatible-pointer-types]
./foundation.h:15:27: note: passing argument to parameter here
cgo-gcc-prolog:125:52: warning: incompatible pointer types passing 'struct NSString *' to parameter of type 'NSString *' [-Wincompatible-pointer-types]
./foundation.h:14:39: note: passing argument to parameter here
cgo-gcc-prolog:143:45: warning: incompatible pointer types passing 'struct NSURL *' to parameter of type 'NSURL *' [-Wincompatible-pointer-types]
./foundation.h:18:34: note: passing argument to parameter here
Индивидуально Компиляция кода Objective- C в XCode не показывает никаких предупреждений, и я чувствую, что CGO -Calls по какой-то причине запутались. Как мне избежать предупреждений здесь?