第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 资源链接

14.8.2 报告问题

报告问题时请包含:

  1. LibreDWG版本
  2. 操作系统和版本
  3. 问题复现步骤
  4. 错误信息(完整)
  5. 示例文件(如可能)
# 获取版本信息
dwgread --version

# 获取详细错误
export LIBREDWG_TRACE=5
dwgread problem.dwg 2>&1 > debug.log

14.9 本章小结

本章介绍了LibreDWG使用中的常见问题和解决方案:

  1. 安装问题:编译、链接、Python绑定
  2. 读取问题:文件读取失败、数据不完整、编码问题
  3. 写入问题:写入失败、数据丢失
  4. 转换问题:DXF/JSON转换
  5. 性能问题:速度和内存优化
  6. 调试技巧:跟踪输出、GDB调试

恭喜! 您已完成LibreDWG完整教程的学习。希望本教程对您的DWG开发工作有所帮助!

posted @ 2026-01-11 00:40  我才是银古  阅读(4)  评论(0)    收藏  举报