You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang导出Android/iOS库时fmt.Print跨平台失效问题解决方法

Go跨Android/iOS打印日志差异原因及解决方案

差异原因

  • print内置函数 vs fmt.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控制台,因此能正常显示。

双平台兼容解决方案

方案1:条件编译实现平台专属日志

利用Go的//go:build条件编译指令,针对Android和iOS分别实现日志输出逻辑,业务代码统一调用封装后的函数即可。

  1. 核心封装代码:
    • 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)))
      }
      
  2. 使用方式:业务代码中直接调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:45:14