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

嵌入式Mono运行时无法从托管程序集打印浮点数求助

问题描述

开发基于Mono脚本的游戏引擎时,在macOS环境下调用float或double类型的ToString()方法会抛出异常,示例代码如下:

public class TestBindingClass
{
    public static void TestManagedMethod()
    {
        Debug.Log(1.0.ToString());
    }
}

抛出的异常栈:

[2023-03-12 01:41:00.576] [info] Exception:   at System.Number.DoubleToNumber (System.Double value, System.Int32 precision, System.Number+NumberBuffer& number) [0x000b2] in <88b1e1b97d1b40bbab202712607ae110>:0 
  at System.Number.FormatSingle (System.Text.ValueStringBuilder& sb, System.Single value, System.ReadOnlySpan`1[T] format, System.Globalization.NumberFormatInfo info) [0x000d1] in <88b1e1b97d1b40bbab202712607ae110>:0 
  at System.Number.FormatSingle (System.Single value, System.String format, System.Globalization.NumberFormatInfo info) [0x0001e] in <88b1e1b97d1b40bbab202712607ae110>:0 
  at System.Single.ToString (System.IFormatProvider provider) [0x00009] in <88b1e1b97d1b40bbab202712607ae110>:0 
  at Helium.TestBindingClass.TestManagedMethod () [0x0005a] in <c5e17dc214154c4c90efd1ec2220c247>:0 

当前CMake中Mono的配置片段:

set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:$ENV{MONO_DIR}/lib/pkgconfig")

target_include_directories(PROJECT_NAME PRIVATE
        $ENV{MONO_DIR}/include/mono-2.0)

message(STATUS "PKG_CONFIG_PATH: $ENV{PKG_CONFIG_PATH}")
execute_process(COMMAND pkg-config --cflags mono-2 OUTPUT_VARIABLE MONO_CFLAGS)
execute_process(COMMAND pkg-config --libs mono-2 OUTPUT_VARIABLE MONO_LIBS)
# remove trailing whitespace
string(STRIP ${MONO_CFLAGS} MONO_CFLAGS)
string(STRIP ${MONO_LIBS} MONO_LIBS)
target_compile_options(PROJECT_NAME PRIVATE ${MONO_CFLAGS})
target_link_libraries(PROJECT_NAME PRIVATE ${MONO_LIBS})
message(STATUS "MONO_CFLAGS: ${MONO_CFLAGS}")
message(STATUS "MONO_LIBS: ${MONO_LIBS}")

已尝试添加额外Mono库、手动加载.NET标准库,但问题未解决。

解决方案

1. 确保Mono运行时能找到正确的BCL程序集

Mono的数字格式化功能依赖基础类库(BCL)的完整实现,需要在引擎初始化阶段指定正确的程序集路径:

  • 通过环境变量设置:启动引擎前执行export MONO_PATH=/path/to/mono/lib/mono/4.5(替换为你的Mono版本对应的BCL目录)
  • 或者在C++初始化代码中调用Mono API设置:
    // 替换为你的Mono安装路径下的BCL目录
    mono_set_assemblies_path("/usr/local/lib/mono/4.5");
    

2. 切换到SGen垃圾回收器的Mono库

macOS下默认的Boehm垃圾回收器可能存在兼容性问题,尝试链接monosgen-2库替代mono-2:
修改CMake中的pkg-config命令:

execute_process(COMMAND pkg-config --cflags monosgen-2 OUTPUT_VARIABLE MONO_CFLAGS)
execute_process(COMMAND pkg-config --libs monosgen-2 OUTPUT_VARIABLE MONO_LIBS)

3. 修复ICU库依赖

Mono的数字格式化依赖ICU处理本地化逻辑,需要确保ICU库已正确安装并被Mono加载:

  • 使用Homebrew安装ICU:brew install icu4c
  • 启动引擎前设置环境变量让Mono找到ICU:export DYLD_LIBRARY_PATH=/usr/local/opt/icu4c/lib:$DYLD_LIBRARY_PATH

4. 手动加载核心依赖程序集

在初始化Mono域后,手动加载格式化所需的核心程序集:

MonoDomain* domain = mono_jit_init("MyGameDomain");
// 加载必要的程序集
mono_domain_assembly_open(domain, "System.Runtime.dll");
mono_domain_assembly_open(domain, "System.Globalization.dll");
mono_domain_assembly_open(domain, "System.Private.CoreLib.dll");

5. 验证Mono版本一致性

确保编译时链接的Mono库版本与运行时使用的BCL版本完全一致:

  • 执行mono --version查看运行时版本
  • 检查$ENV{MONO_DIR}对应的安装版本是否匹配,避免混合不同版本导致的API不兼容

内容的提问来源于stack exchange,提问作者emiliehc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:27:14