Golang导出Android/iOS库时fmt.Print跨平台失效问题解决方法
Go跨Android/iOS打印日志差异原因及解决方案
差异原因
print内置函数 vsfmt.Print标准库函数:两者输出逻辑存在本质区别- Android环境:Go编译为SO库时,
fmt.Print默认输出到系统stdout/stderr,但Android应用的stdout/stderr默认不会转发到Logcat,因此无法看到输出;而内置print函数在Android平台下会直接将内容写入Android原生Log系统,所以能在Logcat中显示。 - iOS环境:Go编译为Framework时,内置
print函数的输出处理逻辑与iOS日志系统不兼容,无法输出到Xcode控制台;而fmt.Print的stdout/stderr会被iOS系统转发到Xcode控制台,因此能正常显示。
- Android环境:Go编译为SO库时,
双平台兼容解决方案
方案1:条件编译实现平台专属日志
利用Go的//go:build条件编译指令,针对Android和iOS分别实现日志输出逻辑,业务代码统一调用封装后的函数即可。
- 核心封装代码:
logger.go(通用声明):package yourpackage // Log 统一日志输出函数 func Log(message string)logger_android.go(Android平台实现)://go:build android package yourpackage /* #include <android/log.h> */ import "C" import "unsafe" func Log(message string) { cTag := C.CString("GoLog") cMsg := C.CString(message) defer func() { C.free(unsafe.Pointer(cTag)) C.free(unsafe.Pointer(cMsg)) }() C.__android_log_print(C.ANDROID_LOG_INFO, cTag, "%s", cMsg) }logger_ios.go(iOS平台实现)://go:build ios package yourpackage /* #import <Foundation/Foundation.h> */ import "C" import "unsafe" func Log(message string) { cMsg := C.CString(message) defer C.free(unsafe.Pointer(cMsg)) C.NSLog(C.CString("%@"), (*C.id)(unsafe.Pointer(cMsg))) }
- 使用方式:业务代码中直接调用
Log("Hello world"),编译时Go会自动匹配对应平台的实现。
方案2:重定向标准输出到平台日志系统
针对Android重定向os.Stdout/os.Stderr到Logcat,iOS保持默认,这样fmt.Print就能在双平台正常输出。
Android平台重定向代码:
//go:build android package yourpackage import ( "io" "os" "unsafe" ) /* #include <android/log.h> */ import "C" type androidLogWriter struct{} func (w androidLogWriter) Write(p []byte) (n int, err error) { cTag := C.CString("GoLog") cMsg := C.CString(string(p)) defer func() { C.free(unsafe.Pointer(cTag)) C.free(unsafe.Pointer(cMsg)) }() C.__android_log_print(C.ANDROID_LOG_INFO, cTag, "%s", cMsg) return len(p), nil } func init() { os.Stdout = androidLogWriter{} os.Stderr = androidLogWriter{} }
完成后,iOS端直接使用fmt.Print即可输出到Xcode控制台,Android端fmt.Print的内容会自动转发到Logcat。
内容的提问来源于stack exchange,提问作者lycstar
相关产品推荐
相关产品推荐

