gpt4 book ai didi

objective-c - 不兼容的指针类型将 'struct NSArray *'传递给'NSArray *类型的参数

转载 作者:行者123 更新时间:2023-12-01 21:11:20 26 4
gpt4 key购买 nike

我正在遵循有关从golang调用Objective-C代码的教程。本教程位于link

代码如下(与本教程相同)

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())
}

基金会
#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();

基金会
#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

在XCode上单独编译Objective-C代码不会显示任何警告,并且我认为CGO-Calls由于某种原因而变得困惑。我如何避免这里的警告?

最佳答案

CGO生成的C.NSString与Objective-C的NSString不兼容。为了避免来自编译器的警告消息,例如const char* nsstring2cstring()中的NSString应该作为objt_code传递到Objective-C代码函数void*中的参数中,并将(foundation.m foundation.h)转换为void*并返回为NSString:

const char* nsstring2cstring(void* s) {
if (s == NULL) { return NULL; }
NSString *cs = *((__unsafe_unretained NSString **)(s));
const char *cstr = [cs UTF8String];
return cstr;
}

C const char* Go代码函数中,需要将 main.go作为 C.NSString传递给 unsafe.Pointer
// NSString -> C string
func cstring(s *C.NSString) *C.char { return C.nsstring2cstring(unsafe.Pointer(s)) }

关于objective-c - 不兼容的指针类型将 'struct NSArray *'传递给'NSArray *类型的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60677904/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com