libdxfrw 实战教程:用免费开源 C++ 库搞定 DXF/DWG 图纸解析与格式转换

📅 2026/8/20 13:26:36
libdxfrw 实战教程:用免费开源 C++ 库搞定 DXF/DWG 图纸解析与格式转换
libdxfrw 实战教程用免费开源 C 库搞定 DXF/DWG 图纸解析与格式转换【免费下载链接】libdxfrwC library to read and write DXF/DWG files项目地址: https://gitcode.com/gh_mirrors/li/libdxfrw在 CAD 文件的世界里有一道隐形的墙DXF 是公开格式任何程序都能解析而 DWG 是协议从未公开的封闭二进制格式想读它过去要么买昂贵的商业 SDK要么绕远路。libdxfrw 正是为拆掉这堵墙而生的免费开源 C 库——它既能读写 DXFASCII 与二进制两种又能解析 R14 到 V2015 的 DWG让 C 工程的图纸解析从此有了免费出口。本文不打算罗列 API而是从这东西到底能干嘛讲到30 行代码跑通读写再送你三个可直接抄的实战场景。一张表看懂能力边界它能做什么、不能做什么先说结论再讲细节。libdxfrw 的能力可以用六条概括DXF 全格式读写ASCII 和二进制 DXF 都能读能写覆盖 R12、2000、2004、2007、2010 五个版本。能解决给你的软件加导出 CAD 图纸功能。DWG 只读解析内置 5 个版本化阅读器dwgreader15/18/21/24/27对应 R14、R2004、R2007、R2010、R2013/R2015。能解决把甲方发来的.dwg变成你能处理的数据。回调接口设计读文件时库里每遇到一个实体就调用你实现的回调函数你不用关心文件内部结构。能解决只提取你关心的数据比如只统计线段。零成本集成CMake、Autotools、Visual Studio、MinGW、Docker 五种构建方式Linux/macOS/Windows 通吃。能解决任何平台上的团队都能用同一套代码。内置多字节编码转换日文 Shift-JIS、简体中文 GB2312、韩文、繁体 Big5 四张码表自动转 UTF-8。能解决中文图纸标题不再变天书。️开箱即用的参考实现仓库自带dwg2dxfDWG 转 DXF和dwg2text提取文字两个完整工具既是生产力又是现成教程。⚠️必须知道的边界越早知道越省钱库不支持 DWG 写入想生成 DWG 请先写 DXF 再借助转换工具绕行许可协议是GPL v2 或更高版本商用闭源集成前务必评估传染性条款。libdxfrw 编译安装教程CMake 四条命令 三套备选方案先拉代码、装依赖。唯一硬性依赖是 libiconv字符编码转换Ubuntu 下执行sudo apt-get install build-essential cmake libiconv-hook-dev git clone https://gitcode.com/gh_mirrors/li/libdxfrw cd libdxfrw mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease # 生成构建配置 cmake --build . --config Release # 编译静态库 sudo cmake --build . --config Release --target install # 安装到系统装完头文件在/usr/local/include/静态库是/usr/local/lib/libdxfrw.a。如果你不在 Ubuntu还有三条备选路线环境方式一句话说明macOSbrew install cmake libiconv后用 CMake与上面命令完全一致Windows打开 vs2013/libdxfrw.sln 直接 Build老 VS 工程向下兼容任意 Linux 发行版./configure make sudo make installAutotools 老派路线批量分发docker/目录下的 4 个 DockerfileAlmaLinux/Ubuntu/Amazon Linux/Alpine一条命令产出多平台二进制包第一个读取程序理解 DRW_Interface 回调接口libdxfrw 的核心设计说穿了就一句话你不去读文件而是让库喂给你数据。你继承DRW_Interface实现关心的回调然后交给dxfRW::read()驱动。打个比方库是一位按清单拆信的档案员你只管告诉它我只关心线段和圆其他信件它自动归档。#include cstdio #include libdxfrw.h // dxfRW 入口类 #include drw_interface.h // DRW_Interface 抽象接口 class MyReader : public DRW_Interface { public: // 头信息图纸版本、单位、全局变量 void addHeader(const DRW_Header* d) override {} // 图层表每遇到一个图层回调一次 void addLayer(const DRW_Layer d) override {} // 块addBlock 到 endBlock 之间的实体都属于该块 void addBlock(const DRW_Block d) override {} void setBlock(const int h) override {} void endBlock() override {} // 我们要统计的两类实体 void addLine(const DRW_Line d) override { printf(LINE (%.2f,%.2f) - (%.2f,%.2f)\n, d.basePoint.x, d.basePoint.y, d.secPoint.x, d.secPoint.y); } void addCircle(const DRW_Circle d) override { printf(CIRCLE center(%.2f,%.2f) r%.2f\n, d.basePoint.x, d.basePoint.y, d.radious); } // 其余几十个纯虚函数照葫芦画瓢补空实现即可—— // 编译器会一条条提醒你这正是兜底清单 }; int main(int argc, char* argv[]) { if (argc 2) return 1; MyReader r; dxfRW dxf(argv[1]); // 传入文件名 // 第二个参数 extfalse 不做 2D 投影保留原始 3D 坐标 bool ok dxf.read(r, false); return ok ? 0 : 1; }编译时链接库即可注意补上-liconvg -o myapp myapp.cpp -ldxfrw -liconv ./myapp drawing.dxf看到终端里逐条打出线段和圆你就已经掌握了读取 DXF的全部真相。顺带一提dwgR类的接口签名与dxfRW完全一致把dxfRW换成dwgR同样的回调就能读 DWG——这一点稍后在实战场景里会放大招。反向写出30 行代码生成一个 DXF 文件读取之外生成文件同样简单在writeEntities()里填充实体指定版本号即可。写出的文件可以直接拖进 CAD 软件打开。#include libdxfrw.h class MyWriter : public DRW_Interface { public: void exportFile(const char* name) { dxfW new dxfRW(name); // 以 AutoCAD 2000(AC1015) 版本写出 ASCII 格式 DXF // 参数依次是回调接口、版本、是否二进制 dxfW-write(this, DRW::AC1015, false); delete dxfW; } void writeHeader(DRW_Header d) override {} void writeBlocks() override {} void writeBlockRecords() override {} void writeEntities() override { // 画一条对角线 DRW_Line l; l.basePoint.x 0; l.basePoint.y 0; l.secPoint.x 100; l.secPoint.y 100; dxfW-writeLine(l); // 画一个圆 DRW_Circle c; c.basePoint.x 50; c.basePoint.y 50; c.radious 25; dxfW-writeCircle(c); } // 其余 write* 回调留空 dxfRW* dxfW; // 写入器指针由我们自己 new 出来注入 };版本号记不住没关系记住这张对应表R12→AC1009、2000→AC1015、2004→AC1018、2007→AC1021、2010→AC1024枚举定义在 src/drw_base.h 里都是 AC 开头别拿 R2000 这种写法硬凑。三个拿来即用的实战场景场景 1批量 DWG 转 DXF用自带的 dwg2dxf不想写代码编译完库之后顺手把dwg2dxf/目录也编出来它就是功能完整的转换器./dwg2dxf input.dwg -v2000 -b output.dxf参数含义-v2000 / -v2004 / -v2007 / -v2010 / -R12指定输出 DXF 版本-b输出二进制 DXF-B批量模式从文本文件读入文件清单统一输出到指定目录-y输出已存在时静默覆盖。为什么这么设计因为转换器复用的是同一套DRW_Interface回调——读进来再写出去天然完成了版本迁移。源码在 dwg2dxf/main.cpp只有 200 行是绝佳的入门教材。场景 2抽取图纸文字dwg2text 与编码处理标注和文字是图纸里最有价值的信息。dwg2text能把 DWG/DXF 里的 TEXT、MTEXT 全部打印到终端./dwg2text drawing.dwg关键在编码图纸里常见 CP932日文 Shift-JIS、CP936简体中文、CP949韩文、CP950繁体libdxfrw 通过 src/intern/drw_textcodec.cpp 与四张码表自动转换你拿到的std::string通常已是 UTF-8。如果乱码优先检查源文件的 code page 声明而不是怀疑库本身——这是新手最容易误判的点。场景 3一套回调打通 DXF/DWG 双格式导入还记得前面说的接口签名一致吗现在把它变成生产力#include libdxfrw.h #include libdwgr.h bool importFile(const char* path, DRW_Interface* cb) { std::string p(path); if (p.size() 4 p.substr(p.size()-4) .dxf) return dxfRW(path).read(cb, false); // DXF 走 dxfRW if (p.size() 4 p.substr(p.size()-4) .dwg) return dwgR(path).read(cb, false); // DWG 走 dwgR return false; }上层业务只认DRW_Interface一种回调底层格式差异被完全屏蔽——这是整个库最值钱的设计。遇到打不开的 DWG用dwgR的getError()/getVersion()配合setDebug(DRW::DEBUG)能快速分清是版本不支持还是文件损坏错误码枚举在 src/drw_base.h 中如BAD_VERSION、BAD_READ_ENTITIES。新手常问的 5 个问题含 3 个解析失败原因错误做法正确做法原因只实现addLine/addCircle其余纯虚函数不写把DRW_Interface全部纯虚函数补上空实现否则编译直接失败用DRW::R2000当版本号用DRW::AC1015或 AC1009/AC1018/AC1021/AC1024版本枚举是 AC 开头编码read()的 ext 参数随手传true需要原始 3D 坐标就传falsetrue会应用 extrusion 投影到 2D悄悄改掉坐标想用库直接写 DWG先写 DXF再用dwg2dxf反向转换库明确不支持 DWG 写入中文乱码就怀疑库先查图纸 code page再查输出端编码见场景 2另外有个隐藏参数值得记住dxf.setEllipseParts(64)可以把椭圆离散成多段线分段数越大越逼近真实椭圆。下游工具不支持椭圆比如老版本 R12时这个参数就是救星。仓库资源地图测试、文档与贡献方式单元测试tests/ 覆盖实体读写、多段线、文字、表格、版本兼容、错误处理等场景cd build ctest一键跑完格式规范SPECIFICATIONS.md 记录了 DXF 格式细节想深入协议的可以当字典查API 文档doxygen libdxfrw.dox即可生成 HTML 版接口文档许可协议完整文本见 COPYINGGPL v2 or later贡献方式老套路——fork、开分支、改代码、补测试、提 PR。项目源自 Rallaz 发起的经典库现由 codelibs 等社区维护仍在持续演进。下一步现在就动手回顾一下你已掌握的东西四条命令完成安装、一个回调接口同时搞定 DXF/DWG 双向读写、一个现成的批量转换工具外加五个高频坑位。从图纸打不开到程序里跑出坐标距离只有一次git clone。现在就去仓库目录下跑一遍dwg2dxf转换手头那张 DWG或者把上面的读取器粘进你的工程——十分钟后的成就感值得你立刻开始。【免费下载链接】libdxfrwC library to read and write DXF/DWG files项目地址: https://gitcode.com/gh_mirrors/li/libdxfrw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考