土木在线论坛 \ 建筑结构 \ 结构设计软件 \ 修改链接器版本跨版本编译ObjecArx

修改链接器版本跨版本编译ObjecArx

发布于:2015-09-14 10:13:14 来自:建筑结构/结构设计软件 [复制转发]
VS2010以后,可以通过toolset方式实现单个IDE,多个版本的编译链接环境生成,这其实也比较麻烦,需要安装低版本的VS(或者绿色安装,注册表导入),VS2002及以后版本VS,安装VC++的时候,需要安装对应版本的.Net框架,非常麻烦。
我在此简单介绍一下,为什么ObjectArx C++编程需要AutoCAD和VC++版本对应。
C++本身是一个开放标准,它定义了用new和delete实现堆上对象内存管理,而操作系统提供的内存API是诸如HeapAlloc/HeapFree之类的Win32函数,这些函数不仅仅是给C\C++用的,任何语言,都可以按约定方式调用。其它如:入口函数,I/O操作等,也是一样的,操作系统只提供通用API接口,C或C++要按自己的标准使用,就必须自己封装实现,比如C语言的malloc ,C++的new ,我平常使用的时候,通常没自己去实现,是因为编译器厂商,已经帮我们做好了,这就是我们通常所说的C运行时,即C Runtime,简称CRT。C++的实现方式通常是跟C语言的一样,或者在C基础上实现的,C\C++共用CRT。
微软发布VC++的时候,不同的VS版本,使用的CRT也是不同的,甚至同个VS版本也可能有多个版本的CRT,原因是诸如BUG修复,淘汰或更新函数接口等。(这儿需要说明的是,VS2014后,这种情况会改善,稍后再提。)
不同版本的CRT是完全不同的东西,他们分别自己管理自己的资源。A版本内的new,不能再另一个版本B的CRT去delete,否则A内存泄露,而B找不到内存分配记录无法delete,造成混乱。
AutoCAD内部对象是用C++管理的,Windows下的AutoCAD使用的就是微软VC++,Autodesk 没为ObjectArx创建底层的内存管理体系,直接使用微软实现的CRT,这带来方便的同时,也要求第三方开发者必须保证CRT一致性。这就是ObjectArx C++编程需要AutoCAD 和 VC++版本对应根本原因。
Autodesk为了保证这一点,煞费苦心,设计了一套能保证CRT不会混淆的机制,比如:要求第三方DLL转导出acrxGetApiVersion函数,这个函数有指纹功能,内部实现有点搞笑,这儿就不说了。此外,AutoCAD在加载DLL的时候,还会对DLL文件数据进行简单校核(这是本文要讨论的问题)。
通常,VC++生成DLL或exe文件,要通过编译,链接,嵌入资源等过程。随着VS版本的不断升级,其中编译过程和链接过程逐渐明确边界,相互独立。
近年来,C++标准快速发展,特别是C++11/14标准发布后,为编程人员带来很多便利,功能更加强大,这儿特别提出auto关键字,lambda函数式…..,真是方便啊!!许多代码逐渐移植到了新C++版本。
这也为ObjectArx开发人员带来麻烦,按新标准写的代码,使用老版本的编译器没法编译,考虑到编译和链接过程分离,相信很多人跟我一样,都不断尝试过用高版本的编译器编译代码,链接却使用AutoCAD对应的低版本库,理论上也做到了CRT版本一致性。
似乎一切都很顺利,编译,链接,VS下完全没问题,用dependency查看,依赖项也正常,但在AutoCAD下面加载却不成功。经过多次的努力,终于用汇编调试跟踪到,AutoCAD加载ARX的时候,还会校验链接器版本号。 后来在网上搜索到,早有人发现这个过程。通过修改生成文件的版本号可以欺骗过AutoCAD过于谨慎的校验,顺利加载。
本人使用VS2010编译器和链接器,使用VS2005的库,在CAD08下测试成功。

此外,这种情况以后会越来越少,微软宣称,VS2014以后,CRT将减少版本更新,而且保持兼容性。
这个家伙什么也没有留下。。。

结构设计软件

返回版块

41.5 万条内容 · 238 人订阅

猜你喜欢

阅读下一篇

csi safe2014 中国规范

本帖最后由 dlynq 于 2015-10-14 16:53 编辑 safe2014中文版至筑信达下载注册机请至 bbs.co188.com/thread-9126008-1-1.html下载

回帖成功

经验值 +10