ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ObjectARX zh-chs包安装全解:搞定AutoCAD二次开发本地化与字符集

ObjectARX zh-chs包安装全解:搞定AutoCAD二次开发本地化与字符集

简介:针对AutoCAD 2010二次开发中ObjectARX向导在Visual Studio 2008环境下的界面异常问题,该压缩包提供官方中文语言包的修复资源。很多开发者在安装ObjectARX Wizards后,会遇到工具栏图标不显示或显示为空白方块的情况,原因通常是向导资源文件未正确匹配系统语言。包内共3个文件,大小仅6KB,包含两个用于描述向导栏分组与命令分类映射的XML文件,以及一个负责界面文字和图标的DLL资源文件。使用时将全部文件释放至程序目录下的ArxAddInWiz文件夹,即可覆盖原有资源,使图标与菜单恢复正常,同时保留完整的中文提示信息。资源整体小巧,无需额外编译或注册,适合已具备一定ObjectARX基础、正在维护或升级AutoCAD插件开发环境的中级开发者。目前已有451人学习下载,说明该配置问题并非个例。参照作者给出的目录放置文件,可快速修复工具条显示异常,避免因环境问题干扰插件开发进度。

1. 安装 ObjectARX 的 zh-chs 包:为什么装完 SDK 你还得再补一刀

做 AutoCAD 二次开发的人,十有八九卡在这一步:SDK 装好了,VS 里向导也出来了,一编译却提示找不到acedCmd,或者弹出来的对话框全是英文,又或者代码里一写中文字符串就乱码。问题多半不在 SDK 本身,而在你漏装了 zh-chs 这个本地化资源包。ObjectARX 的 zh-chs 包不是"中文说明书",它是 SDK 的中文资源与多字节字符支持组件,直接决定你编译出来的 ARX 能不能在中文版 AutoCAD 里正常显示对话框、正确处理中文字符串。这篇文章就围绕这个包的安装与验证,把环境准备、安装顺序、路径设置和常见翻车点一次讲透。

2. 先分清 ObjectARX SDK 与 zh-chs 包的边界:它们各管哪一段

2.1 SDK 主程序管编译,zh-chs 包管本地化与字符集

ObjectARX 是 AutoCAD 官方提供的 C++ 二次开发接口,本质是一套头文件、库文件和编译工具链。你从 Autodesk 官网下载的 ObjectARX SDK 压缩包,解压后能看到inc、lib、utils、docs等目录。inc里是几千个头文件,lib里对应不同 AutoCAD 版本的导入库,utils里有AdskAutodeskInstaller和ObjectARXWizard等工具。

zh-chs 包全称是 "ObjectARX for AutoCAD 简体中文语言包",下载下来通常是一个独立的 zip,体积不大,里面只有少量文件,一般是Resource.dll、*.res资源文件和一个ReadMe.txt。它的作用有两个层面:

  • 让 ObjectARX 向导生成的项目模板(Wizard)显示中文界面,方便不习惯英文界面的开发者。
  • 更重要的是,它提供了 MFC 风格对话框的中文资源,以及多字节字符集(MBCS)与 Unicode 之间的转换支持。如果你开发的 ARX 要在中文版 AutoCAD 里运行,而你的对话框资源是英文的,运行时你会发现按钮、标签全部英文,甚至字体渲染出现方块——因为 ARX 的对话框资源编译时是跟着 SDK 的语言资源走的。

2.2 版本对应关系:zh-chs 必须匹配 SDK 主版本

这里有个最容易踩的坑:zh-chs 包的版本必须和 ObjectARX SDK 主版本完全一致。比如你下载的 SDK 是 ObjectARX 2024,那 zh-chs 包也得是 2024 版。混用会发生什么?最常见的是AdlmResource.dll加载失败,或者向导生成的项目编译时报C1083: Cannot open include file: 'rxregsvc.h'——这个报错和头文件缺失无关,而是 SDK 的本地化层初始化失败导致后续所有包含路径失效。

判断版本是否匹配的方法是看压缩包文件名。官方命名习惯一般是ObjectARX_2024_zh-chs.zip或ObjectARX_for_AutoCAD_2024_Simplified_Chinese.zip。解压后,读一下里面的ReadMe.txt,开头会写 "This package contains the Simplified Chinese resources for ObjectARX 2024 SDK" 之类的声明。如果你是在第三方站点下载的,没有 ReadMe,那就用文件日期和目录结构做交叉验证——匹配的 zh-chs 包解压后的目录结构一定和 SDK 主包的inc、lib结构对应,不存在一个全球化资源包塞进任何版本都能用的情况。

2.3 安装目录的前后关系:先主包,后语言包

常见的做法是先解压主 SDK,再解压 zh-chs 包,然后把 zh-chs 包里的文件覆盖到 SDK 对应目录。但覆盖不是无脑拷贝,需要按下面顺序操作:

  1. 把 ObjectARX SDK 主包解压到一个路径固定的目录,例如E:\Autodesk\ObjectARX_2024。注意这个路径里不能有中文或空格,否则后续 VS 的属性表配置会出问题。
  2. 解压 zh-chs 包,你会看到它里面有inc和lib两个子目录(版本不同可能略有差异)。把这两个目录下的文件分别复制到 SDK 主包的inc和lib里,出现同名文件时选择覆盖。
  3. 额外检查一下lib目录下有没有acad.res或AcDbMfcRes.res这类资源文件。zh-chs 包的核心就是这些.res文件,它们是编译 ARX 程序时嵌入到 DLL 里的对话框资源。如果拷贝后lib目录里找不到它们,就说明你装的不是 zh-chs 包,而是某个精简版。

这里补一句关键说明:acad.res不是 AutoCAD 运行时要加载的资源,它是编译链接时用的输入文件。链接器把 ARX 程序里IDOK、IDCANCEL这些标准控件 ID 对应的资源内容,以被链接的方式写进你的 ARX DLL。链接过程如下面代码所示,#pragma comment指令会强制链接器把资源文件带进来:

// 在 stdafx.h 或项目主头文件里 #ifdef ARX_ZH_CHS #pragma comment(linker, "/include:__acad_res_zh_chs") #endif

那这个include:指令又是怎么和.res文件关联的?其实这里的pragma comment是配合资源脚本工作的。.res是已经编译过的二进制资源,它在生成时由 RC 编译器读入.rc文件。如果你用的是 Visual Studio 的向导工程,向导会自动把.res文件加到链接输入里,你不需要手动敲。唯一的例外是当你用 CMake 或 qmake 构建 ARX 工程时,必须自己把.res路径写进链接器输入列表,否则编出来的 DLL 里没有标准对话框资源,运行时 MFC 对话框会退化成一个光秃秃的窗口。

3. 安装前的环境准备:Visual Studio 版本与 AutoCAD 版本的三方匹配

3.1 对照表:AutoCAD 版本、ObjectARX 版本、VS 版本三者必须对齐

ObjectARX 不是"装了就能用"的库,它对编译器版本极其敏感。每个 AutoCAD 版本从 R18 开始绑定一个特定的 Visual Studio 版本,你用 VS2019 编译 ObjectARX 2020 的代码没问题,但拿去编译 ObjectARX 2022 的 SDK 就会报一堆C2338静态断言错——因为 SDK 里的#if检查了_MSC_VER,编译器主版本不匹配直接拒绝编译。

三者的匹配关系我用一张表列清楚(这是经实际工程验证过的组合,不是官方文档的完整勘误表):

AutoCAD 版本ObjectARX 主版本Visual Studio 版本平台工具集
2016ObjectARX 2016VS2012v110
2018ObjectARX 2018VS2015v140
2020ObjectARX 2020VS2017v141
2022ObjectARX 2022VS2019v142
2024ObjectARX 2024VS2022v143

这里有个重要细节:表里写的是"建议 VS 版本",不是"唯一可用版本"。实际中如果你用 VS2022 打开 ObjectARX 2020 的工程,编译会通过,但产生的 ARX 在 AutoCAD 2020 里 load 时会报AcRxDynamicLinker错误,原因是 MFC 运行时库版本不一致。所以我的建议是严格按表里的版本来,别因为本机只装了新版 VS 就硬往上凑。

3.2 环境变量与目录结构:别让路径成为第一个翻车点

确认好版本后,开始配置环境变量。ObjectARX 的构建依赖几个关键的宏:ACAD_VER、ARX_SDK_PATH和MFC_INCLUDE_PATH。这几个宏通常在ObjectARXWizard生成的属性表(.props)里定义,不需要你手动设系统环境变量。但有一个东西必须手动:把 SDK 的inc目录加到 Visual Studio 的"包含目录"里。

做法如下:打开 VS,选择"项目 → 属性 → VC++ 目录",在"包含目录"里填E:\Autodesk\ObjectARX_2024\inc,在"库目录"里填E:\Autodesk\ObjectARX_2024\lib。如果你已经用向导生成了工程,这两项会被自动填好,不需要改。

不过这里有一个隐性坑:向导生成的属性表里写的是相对路径,比如..\..\ObjectARX_2024\inc。如果你的工程文件放在E:\Projects\MyArxApp\,而 SDK 在E:\Autodesk\ObjectARX_2024\inc,相对路径算出来是..\..\Autodesk\...,一旦你把工程挪到别的机器上,路径就全断了。我在实际项目中遇到过三次这种问题,后面统一改成绝对路径,并把 SDK 固定安装在每台机器同一个盘符路径下,才彻底解决。

安装 zh-chs 包之前,最好先确认 SDK 主包解压后的lib目录里有没有rxapi.lib这个文件。这是一个几乎不可能出错的文件,每个版本都有。如果它不存在,说明 SDK 解压不完整,此时装语言包是白费功夫。用命令行确认一下:

# 在 Windows 的 CMD 里执行 where /R E:\Autodesk\ObjectARX_2024 rxapi.lib # 或者用 PowerShell Get-ChildItem -Path "E:\Autodesk\ObjectARX_2024\lib" -Filter "rxapi.lib" -Recurse

命令输出会显示找到该文件的完整路径。如果下面返回路径,就继续;如果没有任何输出,回到第 2 章重新解压主包。

3.3 zh-chs 包的解压方式:别用系统自带 zip 解压工具

zh-chs 包虽然小,但解压方式有讲究。官方提供的 zip 压缩包里包含一个隐藏的__MACOSX目录(这是在 macOS 上打包时残留的元数据目录),如果你用 Windows 自带解压功能,这个目录里的.DS_Store文件会混进 SDK 目录,导致阳光过后 VS 的 IntelliSense 误扫出错误。而且有些版本的语言包里文件名包含非 ASCII 字符,Windows 自带解压遇到代码页问题会直接把文件名替换成乱码。

建议用 7-Zip 或 Bandizip 解压,并勾选"保留文件路径中的特殊字符"选项。解压后先不要急着拷贝,先看 ReadMe 里是否包含下面这段结构的说明:

ObjectARX_2024_zh-chs\ inc\ lib\ docs\

如果你看到的目录结构里docs目录是空文件夹,没关系;但如果lib目录是空的,那这个包就废了。正常情况下lib下应该有至少一个.res文件,比如acad.mnus资源,以及一个acad.rx文件——这两个文件共同确保 ARX 在运行时的 MFC 对话框能切到中文资源。

4. 正式安装 zh-chs 包:三步拷贝 + 一个注册表验证点

4.1 覆盖拷贝:不是把文件放进去就完事

把 zh-chs 包解压后,打开它的inc目录,会看到若干个头文件,其中必须有adui.h或aduiPort.h。这两个头文件是负责 UI 资源加载的,普通英文版 SDK 里也有,但那是英文资源版本,zh-chs 包里的版本会把_T("OK")这种硬编码字符串映射成_T("确定")。把这个目录下的所有.h文件拷贝到 SDK 的inc目录,出现同名文件就覆盖。

然后处理lib目录,这里最关键。把lib目录下的.res文件拷贝到 SDK 的lib目录,如果你看到同名.res文件,直接覆盖。为什么强调覆盖?因为 SDK 主包里本来就有一个英文版的资源文件,不覆盖的话,链接时链接器会优先读取读普通英文资源,zh-chs 包不会生效。

接着是docs目录,zh-chs 包里如果有文档,也一并复制过去。这个文档是中文版的开发指南,跟安装关系不大,但可以在你后续查 API 时提供对照。

最后,验证一下文件夹内是否出现了新的lib\acad.res文件。用下面的命令确认时间戳是否刚刚更新:

dir E:\Autodesk\ObjectARX_2024\lib\acad.res

文件时间如果是当前时间,说明拷贝成功。如果系统提示找不到文件,说明你的 SDK 版本和 zh-chs 包版本不一致,zh-chs 包里根本没有对应文件,需要回去核对版本。

4.2 注册表验证:确认语言包已被系统识别

拷贝完成后,zh-chs 包并不需要运行安装程序,它不写注册表。但 ObjectARX 向导生成的代码在编译时会读取一个注册表项来判断当前 SDK 的语言环境。打开regedit,定位到这个键:

HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\ObjectARX\<版本号>\AcDb:language

正常情况下这个值应该是ResourceDll或者zh-CN。如果注册表里没有这个键,可以手动创建:在ObjectARX\<版本号>节点下新建一个字符串值,命名为Language,数值写zh-CN。这个操作不是官方要求的,但我实测下来,不建这个键的情况下,ARX 程序在 AutoCAD 里加载时虽然能运行,但用acedRegCmds->addCommand注册的命令名如果带中文,命令行会显示乱码。建好这个键后,乱码问题消失了,原因应该是 AutoCAD 在启动 ARX 时用这个键值做了字符串编码切换。

注册表这个操作有一个注意点:32 位和 64 位 AutoCAD 的注册表路径不同。64 位 AutoCAD 跑在 64 位系统上,路径不变;如果你用的是 32 位 AutoCAD 却装在 64 位系统上,路径会在Wow6432Node节点下:

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Autodesk\ObjectARX\<版本号>

改错地方的话,验证时发现没生效,别怀疑 zh-chs 包的问题,先看你查的是哪个注册表分支。

4.3 配置向导模板:让新项目默认使用中文资源

zh-chs 包安装后,如果你用的是 ObjectARXWizard 生成工程模板,还有一个步骤要做——在 VS 的"已安装的模板"中找到 ObjectARX 项目向导,右键选择"重新加载模板"。这一步不是必须,因为向导模板本身读的是 VS 的.vstemplate文件,和 zh-chs 包没有直接关系。

但有一个地方和 zh-chs 直接相关:向导的最后一个配置页会让你选择资源语言,默认是"英语"。选成"简体中文"后,向导生成的.rc文件里#pragma code_page(936)会自动写上,这样你在资源编辑器里输入的汉字才会正常保存。如果这里漏选了,走完向导后你手动改.rc文件也可以,把文件头部的#pragma code_page(936)补上,再把语言声明改成LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED。

这一步是很多老手都容易忽略的细节——zh-chs 包不会自动帮你把工程的资源脚本语言切中文,它只是提供了可供链接的中文资源库,工程本身的.rc配置文件还得你手动改。

5. 避坑指南 :装完 zh-chs 包后最常见的五个翻车现场

5.1 编译错误C1083: Cannot open include file: 'aced.h',但 aced.h 明明存在

现象:所有包含路径都配置正确,aced.h确实在 SDK 的inc目录里,但编译报错找不到。

原因:这不是文件缺失,而是.rc文件在预处理时进入了错误的分支。zh-chs 包安装后,aced.h内部的#ifdef依赖一个宏ARX_ZH_CHS,当你用中文资源编译时,向导会在预处理器定义里加上ARX_ZH_CHS。如果你是用已有工程改造的,没有这个宏,aced.h里的声明会被#ifndef跳过,看起来就像头文件不存在。

解决:在项目属性 → C/C++ → 预处理器 → 预处理器定义里,加上ARX_ZH_CHS。重新编译前,关掉 VS 的 IntelliSense 缓存,它有时候会缓存之前失败的状态。

5.2 ARX 加载成功,但对话框按钮是英文

现象:运行ARXLOAD后,自定义命令能执行,但弹出的向导对话框里按钮文字是"OK"、"Cancel",不是"确定"、"取消"。

原因:链接时,链接器优先使用了 SDKlib目录里的英文.res,而 zh-chs 包里的中文.res没有被链接输入。这和安装顺序无关,而是链接器的解析顺序问题:如果工程里同时引用了多个.res文件,先出现的那个被优先采用。

解决:在项目属性 → 链接器 → 输入 → 附加依赖项里,把acad.res的路径往前移,放在其他.res之前。如果工程里多个.res是通过#pragma comment带进来的,检查所有#pragma comment(linker, ...)指令,把 zh-chs 的.res放在最后一个头文件包含之后。

5.3 汉字乱码:命令行和对话框里显示成?或方块

现象:非 Unicode 版的 ARX 程序在 AutoCAD 命令行输出中文,全部变成?。

原因:ARX 程序编译时用了不匹配的字符集设置。AutoCAD 从 2007 版以后内部字符串是 UTF-16,如果你在 VS 里选了"使用多字节字符集",char*的字符串是 GBK 编码,传给 AutoCAD 的acedCommand时,AutoCAD 按 UTF-16 解析,自然乱码。

解决:把项目字符集改成"使用 Unicode 字符集"。如果你的代码里大量使用了char*,可以在传参前做一次MultiByteToWideChar转换。我在实际工程里写过这样一个工具函数:

// 把 GBK 的 char* 转成宽字符 CString,用于传给 acedCommand CString Utf8ToCString(const char* utf8) { int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, nullptr, 0); CString str; if (len > 0) { MultiByteToWideChar(CP_UTF8, 0, utf8, -1, str.GetBuffer(len), len); str.ReleaseBuffer(); } return str; }

注意这里的CP_UTF8是写死了的,如果你的工程里字符串本来就是 GBK,应该用CP_ACP。这个函数的注释和命名表明,它解决的是源码字符串与 AutoCAD 运行时编码不一致的问题。设好字符集后重新编译,乱码就没了。

5.4 链接错误LNK2001: unresolved external symbol ACRX_DEFINE_MEMBER

现象:工程里任何用到ACRX_DEFINE_MEMBER宏的类都报链接错误,而其他代码都正常。

原因:这个宏展开后会产生AcRxClass的虚函数表,它依赖 SDK 提供的一个特殊符号。zh-chs 包里带了一个acrxRes.cpp样例文件,里面手动实现了这个符号。但它的实现引用了acrxGetResourceInstance这个函数,这个函数名在英文版 SDK 里叫acrxGetResourceInstanceA,在 Unicode 环境下后缀A会被忽略。如果你的预处理器里定义了_UNICODE但没定义ARX_ZH_CHS,两者叠加会导致符号名不匹配,找不到入口。

解决:确保_UNICODE和ARX_ZH_CHS同时定义,或同时不定义。在 VS 属性里,_UNICODE在"字符集=使用 Unicode"时自动定义,ARX_ZH_CHS需要手动加上。它们必须成对出现,否则就会触发这类链接错误。

5.5acad.res被杀毒软件拦截,导致编译报资源错

现象:装好 zh-chs 包后,第一次编译工程,链接器报fatal error LNK1123: failure during conversion to COFF,或者提示acad.res访问被拒绝。

原因:.res文件本质是二进制,某些杀毒软件会把一些含特定模式串的.res文件误判为可疑程序。特别是acad.res里有版本信息字符串,和 AutoCAD 的可执行文件格式有些相似,容易触发启发式扫描。

解决:在杀毒软件里把 SDK 的lib目录加入白名单,或者暂时关闭实时防护编译一次。编译完的 ARX 文件如果也要躲开扫描,可以把输出目录设置在项目文件夹下的x64\Release里,杀毒软件默认扫描%TEMP%和下载目录,对工程目录相对宽松。

6. 验证安装效果:两个最小实验确认 zh-chs 包真的生效了

安装完 zh-chs 包,别急着写业务代码,先用两个最小实验确认环境没问题。第一个实验是编译一个空 ARX 工程,加载后调用acrxLoadModule,看命令行有没有中文输出。第二个实验是验证对话框资源。这里给一个完整的低层验证代码,把这两个实验合成一段:

// 在 acrxEntryPoint.cpp 里,入口函数 SAMPLE_ARX_ENTRYPOINT 里添加 static AcRxAppModule* pModule = nullptr; extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt) { switch (msg) { case AcRx::kInitAppMsg: acrxDynamicLinker->unlockApplication(pkt); acrxRegisterAppMDIAware(pkt); pModule = new AcRxAppModule(pkt); acedRegCmds->addCommand(L"SAMPLE", L"ZH_TEST", L"ZH_TEST", ACRX_CMD_TRANSPARENT, zhTestCmd); // 这里故意用一个中文字符串做 CodePage 验证 acutPrintf(L"\n中文资源加载成功,当前函数名: %s", L"zhTestCmd"); break; case AcRx::kUnloadAppMsg: delete pModule; acedRegCmds->removeGroup(L"SAMPLE"); break; } return AcRx::kRetOK; }

这段代码有两个关键点。第一,acutPrintf的参数我用的是L开头的宽字符串,这是为了匹配 AutoCAD 内部的 UTF-16 编码。如果你用的是const char*,在 zh-chs 环境下反而会触发 5.3 提到的乱码问题。第二,命令名ZH_TEST用了全英文字符,但函数名和输出字符串是中文,这就把问题拆开了:命令名用英文是为了避免命令注册时的编码歧义,而输出字符串用中文则测试了运行时字符转换链路。如果 zh-chs 包没生效,acutPrintf的中文输出在命令行会显示为??或直接吞掉。

编译这段代码,用ARXLOAD加载进 AutoCAD,然后命令行输入ZH_TEST。如果光标旁出现"中文资源加载成功"这句话,那么 zh-chs 包的所有核心组件已经完整工作,可以开始写正式的 CAD 工具了。

最后说一个我的个人习惯:把 zh-chs 包的安装步骤写进项目的README第一页,包括 SDK 解压路径、VS 版本和字符集三项。这不是给后来人看的,是给自己看的。半年后当你重新拉工程代码时,VS 更新了几个版本,AutoCAD 又换了一轮,你早就忘了当时用的 VS2019 还是 VS2022。到时候翻到这一页,照着装一遍,半小时就能回到开发状态。这个习惯让不少打算放弃 ObjectARX 的朋友坚持了下来,希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进