使用Raylib的DrawTextEx函数显示俄文文本时遇Unicode乱码及指针类型不兼容警告问题求助
使用Raylib的DrawTextEx函数显示俄文文本时遇Unicode乱码及指针类型不兼容警告问题求助
看起来你碰到了两个关联的问题:编译时的指针类型不兼容警告,以及俄文Unicode文本显示乱码。咱们一步步来拆解解决:
问题根源分析
- 指针类型警告:Raylib的
DrawTextEx函数默认接受的是const char*类型的UTF-8字符串,但你传入的是wchar_t*宽字符指针,类型不匹配所以触发警告。 - 乱码问题:一是你注释掉了
setlocale调用,宽字符的处理依赖正确的区域设置;二是可能你的字体不支持西里尔字母(俄文),或者没有用对Raylib的宽字符处理API。
具体解决方案
方案一:直接使用Raylib的宽字符专用函数
Raylib提供了后缀为W的宽字符版本API,比如DrawTextExW和MeasureTextExW,专门用来处理wchar_t*类型的字符串,这样能完美匹配你的变量类型:
#include <stdio.h> #include <wchar.h> #include <locale.h> #include "raylib.h" #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 #define TARGET_FPS 60 int main(int argc, char const *argv[]) { // 根据系统设置正确的区域,Windows和Linux/macOS有差异 #ifdef _WIN32 setlocale(LC_ALL, "Russian_Russia.1251"); #else setlocale(LC_ALL, "ru_RU.UTF-8"); #endif InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "unicode"); wchar_t msg[] = L"Текст, Text."; // 务必确保加载的字体支持西里尔字母(俄文),比如PT Mono是支持的,但要确认文件路径正确 Font font = LoadFontEx("resources/pt-mono_regular.ttf", 48, NULL, 0); SetTargetFPS(TARGET_FPS); while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(WHITE); // 用MeasureTextExW计算文本尺寸,实现居中显示 Vector2 textSize = MeasureTextExW(font, msg, 48, 2); DrawTextExW(font, msg, (Vector2) { (float)WINDOW_WIDTH/2 - textSize.x/2, (float)WINDOW_HEIGHT/2 - textSize.y/2 }, 48, 2, BLACK); EndDrawing(); } UnloadFont(font); CloseWindow(); return 0; }
方案二:将宽字符转换为UTF-8字符串(更通用)
如果更习惯用普通的DrawTextEx,可以把wchar_t字符串转换为UTF-8编码的char*字符串,Raylib的普通API对UTF-8支持很好:
#include <stdio.h> #include <wchar.h> #include <locale.h> #include <stdlib.h> #include <string.h> #include "raylib.h" #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 #define TARGET_FPS 60 int main(int argc, char const *argv[]) { // 自动匹配系统区域设置,兼容性更强 setlocale(LC_ALL, ""); InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "unicode"); wchar_t msg_w[] = L"Текст, Text."; // 计算转换为UTF-8所需的缓冲区大小 size_t utf8_buf_size = wcstombs(NULL, msg_w, 0) + 1; char* msg_utf8 = malloc(utf8_buf_size); // 执行宽字符到UTF-8的转换 wcstombs(msg_utf8, msg_w, utf8_buf_size); Font font = LoadFontEx("resources/pt-mono_regular.ttf", 48, NULL, 0); SetTargetFPS(TARGET_FPS); while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(WHITE); // 计算文本尺寸实现居中 Vector2 textSize = MeasureTextEx(font, msg_utf8, 48, 2); DrawTextEx(font, msg_utf8, (Vector2) { (float)WINDOW_WIDTH/2 - textSize.x/2, (float)WINDOW_HEIGHT/2 - textSize.y/2 }, 48, 2, BLACK); EndDrawing(); } // 记得释放动态分配的内存 free(msg_utf8); UnloadFont(font); CloseWindow(); return 0; }
额外注意事项
- 字体兼容性:一定要确认你加载的
pt-mono_regular.ttf包含西里尔字母,有些英文字体没有俄文字符,会显示方框或乱码;如果不确定,可以换用系统自带的支持俄文的字体(比如Windows的Arial,Linux的DejaVu Sans)。 - 区域设置:不要注释掉
setlocale,宽字符的转换和显示依赖正确的区域配置,否则会出现编码错误。 - 文本居中:原代码里直接把绘制起点设为窗口中心,实际上文本是从左上角开始绘制的,所以会偏右偏下,用
MeasureTextEx(或宽字符版本)计算尺寸后再调整位置才能真正居中。
备注:内容来源于stack exchange,提问作者Alexander Danilenko
相关产品推荐
相关产品推荐

