嵌入式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
相关产品推荐
相关产品推荐

