第14章 - 常见问题与故障排除
第14章 - 常见问题与故障排除
14.1 安装问题
14.1.1 编译错误
问题:configure失败,找不到依赖
checking for LIBTOOL... no
configure: error: libtool is required
解决方案:
# Ubuntu/Debian
sudo apt install libtool autoconf automake
# Fedora/RHEL
sudo dnf install libtool autoconf automake
# macOS
brew install libtool autoconf automake
问题:make时编译错误
error: 'DWG_TYPE_XXX' undeclared
解决方案:
# 确保头文件路径正确
# 重新运行autogen.sh和configure
sh ./autogen.sh
./configure
make clean
make
问题:SWIG相关错误
error: swig command not found
解决方案:
# 安装SWIG
sudo apt install swig
# 或禁用绑定
./configure --disable-bindings
14.1.2 链接错误
问题:找不到共享库
error while loading shared libraries: libredwg.so: cannot open shared object file
解决方案:
# 方法1:更新库缓存
sudo ldconfig
# 方法2:设置库路径
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
# 方法3:永久添加到配置
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/libredwg.conf
sudo ldconfig
问题:链接时找不到符号
undefined reference to `dwg_read_file'
解决方案:
# 确保链接顺序正确,库放在最后
gcc main.c -o main -lredwg
# 检查库是否安装
ldconfig -p | grep libredwg
# 检查pkg-config
pkg-config --libs libredwg
14.1.3 Python绑定问题
问题:import libredwg失败
ImportError: No module named 'libredwg'
解决方案:
# 重新构建Python绑定
cd libredwg/bindings/python
python3 setup.py build
python3 setup.py install --user
# 或使用pip
pip install .
# 检查安装位置
python3 -c "import libredwg; print(libredwg.__file__)"
问题:Python绑定版本不匹配
ImportError: libredwg.so: undefined symbol: ...
解决方案:
# 重新编译整个项目
cd libredwg
make clean
./configure --enable-python
make
sudo make install
14.2 读取问题
14.2.1 文件读取失败
问题:无法读取DWG文件
dwg_read_file returned DWG_ERR_INVALIDDWG
诊断步骤:
# 1. 检查文件是否存在
ls -la file.dwg
# 2. 检查文件魔数
hexdump -C file.dwg | head -1
# 应该看到 "AC10xx" 开头
# 3. 使用详细模式
export LIBREDWG_TRACE=3
dwgread file.dwg
# 4. 尝试用dwg2dxf测试
dwg2dxf -v file.dwg
常见原因和解决方案:
| 原因 | 解决方案 |
|---|---|
| 文件损坏 | 尝试用AutoCAD打开并另存 |
| 加密文件 | LibreDWG不支持加密DWG |
| 版本过新 | 等待LibreDWG更新或降级保存 |
| 非标准格式 | 检查是否为第三方软件生成 |
问题:读取返回非零但数据正常
int error = dwg_read_file("file.dwg", &dwg);
// error = 0x12 但数据看起来正常
解释:
// 错误码是位掩码,非严重错误可以继续使用
if (error >= DWG_ERR_CRITICAL) { // >= 0x2000
// 严重错误,无法继续
} else if (error) {
// 非严重警告,可以继续
// 常见警告:
// DWG_ERR_WRONGCRC (1) - CRC校验失败
// DWG_ERR_NOTYETSUPPORTED (2) - 某些功能不支持
// DWG_ERR_UNHANDLEDCLASS (4) - 未处理的类
}
14.2.2 数据不完整
问题:某些对象为NULL
Dwg_Object *obj = &dwg.object[i];
if (obj->tio.entity == NULL) { // NULL!
// ...
}
解决方案:
// 始终检查空指针
for (BITCODE_BL i = 0; i < dwg.num_objects; i++) {
Dwg_Object *obj = &dwg.object[i];
// 检查对象有效性
if (!obj || obj->type == 0) continue;
// 检查实体数据
if (obj->supertype == DWG_SUPERTYPE_ENTITY) {
if (!obj->tio.entity) continue;
if (!obj->tio.entity->tio.LINE) continue; // 假设是LINE
// 现在可以安全访问
}
}
问题:句柄引用未解析
Dwg_Object_Entity *ent = obj->tio.entity;
if (ent->layer) {
// ent->layer->obj 可能是NULL
Dwg_Object *layer_obj = ent->layer->obj; // 可能崩溃
}
解决方案:
// 确保引用已解析
if (dwg.dirty_refs) {
dwg_resolve_objectrefs_silent(&dwg);
}
// 安全访问引用
char* get_entity_layer_name(Dwg_Data *dwg, Dwg_Object *obj)
{
if (obj->supertype != DWG_SUPERTYPE_ENTITY) return "0";
Dwg_Object_Entity *ent = obj->tio.entity;
if (!ent) return "0";
if (!ent->layer) return "0";
if (!ent->layer->obj) return "0";
Dwg_Object *layer_obj = ent->layer->obj;
if (layer_obj->fixedtype != DWG_TYPE_LAYER) return "0";
Dwg_Object_LAYER *layer = layer_obj->tio.object->tio.LAYER;
return layer->name ? layer->name : "0";
}
14.2.3 字符编码问题
问题:中文乱码
文字内容显示为: ????
解决方案:
// 检查DWG的代码页
printf("代码页: %d\n", dwg.header.codepage);
// 常见代码页:
// 30 = ANSI_1252 (西欧)
// 31 = ANSI_1251 (西里尔)
// 936 = GBK (简体中文)
// 950 = Big5 (繁体中文)
// 使用iconv转换编码
#include <iconv.h>
char* convert_encoding(const char *input, const char *from, const char *to)
{
iconv_t cd = iconv_open(to, from);
if (cd == (iconv_t)-1) return NULL;
size_t in_len = strlen(input);
size_t out_len = in_len * 4;
char *output = malloc(out_len + 1);
char *in_ptr = (char*)input;
char *out_ptr = output;
iconv(cd, &in_ptr, &in_len, &out_ptr, &out_len);
*out_ptr = '\0';
iconv_close(cd);
return output;
}
// 使用示例
char *utf8_text = convert_encoding(text->text_value, "GBK", "UTF-8");
14.3 写入问题
14.3.1 写入失败
问题:dwg_write_file返回错误
int error = dwg_write_file("output.dwg", &dwg);
// error != 0
诊断步骤:
// 1. 检查版本
printf("版本: %d\n", dwg.header.version);
// R2000 (15) 支持最好
// 2. 检查对象完整性
for (BITCODE_BL i = 0; i < dwg.num_objects; i++) {
Dwg_Object *obj = &dwg.object[i];
if (obj->handle.value == 0) {
printf("警告: 对象 %lu 句柄为0\n", (unsigned long)i);
}
}
// 3. 使用详细模式
export LIBREDWG_TRACE=5
常见原因:
- 版本不支持(R2004+实验性)
- 对象结构不完整
- 句柄引用无效
问题:写入的DWG无法用AutoCAD打开
解决方案:
# 1. 确保使用R2000版本
dwg.header.version = R_2000;
# 2. 尝试通过DXF中转
dwg2dxf output.dwg -o temp.dxf
# 用AutoCAD打开DXF
# 3. 检查对象有效性
dwgread -v output.dwg
14.3.2 数据丢失
问题:某些实体未写入
// 添加了实体但写入后不存在
检查清单:
// 1. 确保实体添加到模型空间
// 需要正确设置ownerhandle
// 2. 确保句柄有效
obj->handle.value = next_handle++;
// 3. 确保类型正确
obj->type = DWG_TYPE_LINE;
obj->fixedtype = DWG_TYPE_LINE;
obj->supertype = DWG_SUPERTYPE_ENTITY;
// 4. 确保parent指针正确
obj->parent = dwg;
obj->tio.entity->parent = obj;
14.4 转换问题
14.4.1 DXF转换问题
问题:dwg2dxf输出为空或损坏
dwg2dxf file.dwg -o output.dxf
# output.dxf 为空或无法打开
解决方案:
# 使用详细模式查看错误
dwg2dxf -v -v file.dwg -o output.dxf 2>&1 | head -100
# 尝试不同版本
dwg2dxf -r r14 file.dwg -o output.dxf
# 检查输入文件
dwgread file.dwg
问题:DXF精度问题
坐标精度丢失,如 100.123456789 变成 100.1235
解决方案:
# 重新编译时设置精度
./configure --with-dxf-precision=12
make clean && make
# 或使用JSON格式保留完整精度
dwgread -o json file.dwg > file.json
14.4.2 JSON转换问题
问题:JSON文件过大
# 大型DWG转JSON后文件很大
解决方案:
# 压缩输出
dwgread -o json file.dwg | gzip > file.json.gz
# 或只提取需要的数据
dwgread -o json file.dwg | jq -c '.objects[] | select(.type == "LINE")' > lines.json
14.5 性能问题
14.5.1 读取速度慢
问题:大文件读取时间长
诊断:
time dwgread large_file.dwg > /dev/null
优化方案:
// 1. 避免重复读取
static Dwg_Data *cached_dwg = NULL;
static char *cached_filename = NULL;
// 2. 使用增量处理
// 按需加载,不一次性加载所有对象
// 3. 禁用不需要的功能
dwg.opts &= ~DWG_OPTS_IN; // 减少日志输出
14.5.2 内存使用高
问题:处理大文件时内存不足
解决方案:
// 1. 及时释放不需要的数据
dwg_free(&dwg);
// 2. 分批处理
for (int batch = 0; batch < num_files; batch++) {
process_file(files[batch]);
// 每批处理后内存自动释放
}
// 3. 监控内存使用
#include <sys/resource.h>
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
printf("内存使用: %ld KB\n", usage.ru_maxrss);
14.6 调试技巧
14.6.1 使用跟踪输出
# 设置跟踪级别(0-9)
export LIBREDWG_TRACE=3
# 级别说明:
# 0 = 无输出
# 1 = 错误
# 2 = 警告
# 3 = 信息
# 4-6 = 详细
# 7-9 = 调试
14.6.2 使用GDB调试
# 编译调试版本
./configure --enable-debug CFLAGS="-g -O0"
make
# 使用GDB
gdb --args dwgread problem_file.dwg
# 在GDB中
(gdb) break dwg_read_file
(gdb) run
(gdb) bt # 查看调用栈
14.6.3 检查DWG结构
// 打印DWG结构信息
void dump_dwg_info(Dwg_Data *dwg)
{
printf("=== DWG 信息 ===\n");
printf("版本: %s\n", dwg->header.version);
printf("对象数: %lu\n", (unsigned long)dwg->num_objects);
printf("类数: %lu\n", (unsigned long)dwg->num_classes);
printf("\n=== 对象类型分布 ===\n");
int type_counts[100] = {0};
for (BITCODE_BL i = 0; i < dwg->num_objects; i++) {
int type = dwg->object[i].fixedtype;
if (type >= 0 && type < 100) {
type_counts[type]++;
}
}
for (int i = 0; i < 100; i++) {
if (type_counts[i] > 0) {
printf(" 类型 %d: %d\n", i, type_counts[i]);
}
}
}
14.7 常见错误代码
| 错误码 | 名称 | 说明 | 解决方案 |
|---|---|---|---|
| 0x0001 | DWG_ERR_WRONGCRC | CRC校验失败 | 文件可能损坏,尝试修复 |
| 0x0002 | DWG_ERR_NOTYETSUPPORTED | 功能不支持 | 等待更新或使用替代方案 |
| 0x0004 | DWG_ERR_UNHANDLEDCLASS | 未处理的类 | 可忽略或报告问题 |
| 0x0008 | DWG_ERR_INVALIDTYPE | 无效类型 | 检查文件完整性 |
| 0x0010 | DWG_ERR_INVALIDHANDLE | 无效句柄 | 解析引用可能有问题 |
| 0x0800 | DWG_ERR_OUTOFMEM | 内存不足 | 增加内存或分批处理 |
| 0x1000 | DWG_ERR_INVALIDDWG | 无效DWG | 检查文件格式 |
| 0x2000 | DWG_ERR_IOERROR | IO错误 | 检查文件权限和路径 |
14.8 获取帮助
14.8.1 资源链接
- GitHub仓库: https://github.com/LibreDWG/libredwg
- 问题追踪: https://github.com/LibreDWG/libredwg/issues
- GNU项目: http://www.gnu.org/software/libredwg/
- API文档: https://www.gnu.org/software/libredwg/refman/
14.8.2 报告问题
报告问题时请包含:
- LibreDWG版本
- 操作系统和版本
- 问题复现步骤
- 错误信息(完整)
- 示例文件(如可能)
# 获取版本信息
dwgread --version
# 获取详细错误
export LIBREDWG_TRACE=5
dwgread problem.dwg 2>&1 > debug.log
14.9 本章小结
本章介绍了LibreDWG使用中的常见问题和解决方案:
- 安装问题:编译、链接、Python绑定
- 读取问题:文件读取失败、数据不完整、编码问题
- 写入问题:写入失败、数据丢失
- 转换问题:DXF/JSON转换
- 性能问题:速度和内存优化
- 调试技巧:跟踪输出、GDB调试
恭喜! 您已完成LibreDWG完整教程的学习。希望本教程对您的DWG开发工作有所帮助!

浙公网安备 33010602011771号