【VC++开源代码栏目提醒】:本文主要为网学会员提供“unix - 操作系统”,希望对需要unix - 操作系统网友有所帮助,学习一下!
?? 用四叉树管理散布在平面上的对象 返回首页 三人成虎 ?? Windows 和 Unix 下动态链接库的区别 最近慢慢将开发环境转向了 freebsd 渐渐的发现了许多东西跟 Windows 下不太一样。
我指的是跟我以前想当然的理解不太一样。
比如unix 下对动态链接库 so 的处理和 Windows 下的 DLL 就不太相同。
之前我对 Windows 下更为了解一些。
早几年做 Windows 开发老是为动态链接静态链接这些问题纠缠不清慢慢的才有了比较清晰的理解现在基本上不会为这类问题困绕了。
前段时间碰到一些朋友写 lua 的扩展库windows 版本时遇到的几个 bug 就是因为链接问题导致的。
公司内部的一个项目在服务器程序上也碰到了错误链接 lua 引起的 bug 在内部 maillist 上争论了好久。
当时作为 windows 程序员跟同事中的 unix 程序员争论看似相同的问题时却老说不到一起去今天才发现原来是相互之间对动态链接库的理解不同导致的。
今天写下本文或许可以让以后跨平台开发的朋友少走点弯路。
动态链接库在 unix 下习惯以 .so 为文件名结尾通常还以 lib 开头。
而 Windows 下是以 .DLL 为文件后缀。
Windows 在处理 dll 上还有一些细节容易被人忽略我曾经为这个写过一篇 Blog。
如果需要运行时主动加载一个动态链接库windows 下可以使用 LoadLibrary 这个 kernel API 在 kernel32.dll 中unix 下是用 dlopen 。
Windows 下找到 dll 中导出符号的地址可以用 GetProcAddress 而 unix 也有对应的 api ... 这些相互对应的 api 似乎预示着对等的功能但事实上是有区别的。
DLL 事实上和 EXE 文件一样同属 PE 格式的执行文件。
对于隐式的引用外部符号需要把外部符号所在的位置写在 PE 头上。
PE 加载器将从 PE 头上找到依赖的符号表并加载依赖的其它 DLL 文件。
但是unix 上并非如此so 文件大多为 elf 执行文件格式。
当它们需要的外部符号可以不写明这些符号所在的位置。
也就是说通常 so 文件本身并不知道它依赖的那些符号在哪些 so 里面。
这些符号是由调用 dlopen 的进程运行时提供的。
而 unix 下的执行文件本身会暴露自己静态链接的符号可以是自己本身实现的或者是从静态库 .a 文件里链入的。
dlopen 将把这些符号通报给 dlopen 加载的 .so 文件最终完成动态链接。
事实上 dlopen 还可以指定 mode 完成更复杂的操作 因为这个区别unix 下的 lua 解释器可以完全静态链接所有的 lua api 我们为 lua 扩展的库以 so 的形式存在被运行时加载不会有任何隐患。
而 Windows 下必须生成一个 luacore 的 DLL 文件由 lua 解释器于扩展库共享 lua api 还包括 crt 的实现 才不会出问题。
也因为这个区别
VC 下才会有让 windows 开发新手困惑不解的动态链接 CRT 静态链接 CRT 多线程库单线程库等等的选项。
没点点 windows 开发功力的人多少都要在上面栽几个跟头。
从动态链接库的这个设计上来看我个人感觉Windows 弄的真是糟糕透顶。
尤其是对开发者来说是这样。
至少我们在 windows 下做一个 dll 文件给大家使用还需要携带一个 .lib 文件而 unix 下一般只需要有相应的头文件就够了。
对于编写新的 .so 找不到的符号可以就让它在那里直到最终执行文件来把所有需要的符号联合到一起。
windows 可以存在一个 dll 对另一个 dll 的隐式依赖而 unix 下一般不需要让 so 和 so 有隐式依赖关系。
这让我们全局替换类似 CRT 的东西变的困难许多而以我自己的编程经验来看好处却没有多少。
顺便一提的是 unix 下需要用 ldconfig 来管理动态库这比 windows 下 copy DLL 到当前目录下就可以用的方式无疑提高了系统的安全性。
云风 提交于 November 1 2006 07:01 PM 固定链接 / Memory DLL loading code Version 0.0.2 Copyright c 2004-2005 by Joachim Bauch / mailjoachim-bauch.de http://www.joachim-bauch.de The contents of this file are subject to the Mozilla Public License Version 1.1 the quotLicensequot you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an quotAS ISquot basis WITHOUT WARRANTY OF ANY KIND either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is MemoryModule.c The Initial Developer of the Original Code is Joachim Bauch. Portions created by Joachim Bauch are Copyright C 2004-2005 Joachim Bauch. All Rights Reserved. / Posted by: zzz654321 117 July 6 2009 05:25 PM / Memory DLL loading code Version 0.0.2 Copyright c 2004-2005 by Joachim Bauch / mailjoachim-bauch.de http://www.joachim-bauch.de The contents of this file are subject to the Mozilla Public License Version 1.1 the quotLicensequot you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an quotAS ISquot basis WITHOUT WARRANTY OF ANY KIND either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is MemoryModule.c The Initial Developer of the Original Code is Joachim Bauch. Portions created by Joachim Bauch are Copyright C 2004-2005 Joachim Bauch. All Rights Reserved. / Posted by: Anonymous 116 July 6 2009 05:24 PM 关于这个“unix 下需要用 ldconfig 来管理动态库” Linux 下是可以用 LD_LIBRARY_PATH. 环境变量来直接用 copy 到目录的 .so Posted by: 山猫 115 July 10 2008 02:34 AM est 网上邻居里运行程序不是通过 RPC 方式的哦 :D 你运行别人机器上的程序执行
代码的还是你自己的 CPU 而不是远程的。
而 RPC 通常指在远程运行
代码通过协议传递输入输出数据。
这的确是在非本地文件系统上运行程序。
不过我前面意思表达的不清楚不是想说这个。
在我看到的范畴内windows 系统上执行一个 exe 或 dll 都要求有一个 image path 。
远程文件也是有这个 image path 的只不过是用 开头。
其解析的过程可以由 netbios 来完成。
我没有找到方法在 windows 下自己写一段程序凭空加载一个 DLL 数据块 没有 image path 的仅仅是我的进程空间内的一个数据块而不需要自己去解析 PE 格式。
Posted by: Cloud 114 June 2 2008 10:11 PM 怎么以系统的方式从非本地文件加载DLL 网上邻居的游戏直接双击就可以运行这个应该是通过RPC调用的exe和dll吧 Posted by: est 113 June 2 2008 08:04 PM 那个anonymous和enterpriseing什么鸟人在这一知半解的玩弄文字概念说了半天我也没觉得你说的有什么实质意义 什么流不流的同样是signalunix signal和windows还有一些应用层的意义就不一样根本不是一回事有的甚至是event争个鸟。
unix是30年前的又怎么样老的东西不能描述现代的情况不代表落后人家可以很方便的“进化”一下dll和so真有这么本质的区别什么兼容不兼容的和dll有关系吗是先进性的体现 我怎么看glibc可以往前兼容呢。
讲废话的人太多都没讲到点子上还那么多废话。
废话多的人就有问题搞了半天文字概念也没搞清楚。
搞这行讲的是悟性不是牛b.牛b等于菜鸟是自我感觉良好。
假牛b一看就知道还冲老大什么现在结构就是微内核。
我看你简单就是美都没领悟 Posted by: 1 112 June 1 2007 07:06 PM 还是加上审核吧 Posted by: Atry 111 March 19 2007 11:15 AM 每个DLL有自己的namespace因此不同的DLL可以有同名的函数。
所有使用so的image共享同一个namespaceso 可以指定需要连接哪些so需要哪些函数却无法指定函数在哪个so里。
而dll生成后要依赖的函数所在其他dll就固定死了。
Linux 内合理也是这个样子所以符号冲突的概率要比 windows 内核驱动大得多。
Posted by: chen3feng 110 January 19 2007 12:41 AM 楼下已经写过了 : quot理论上 windows 下编译器在生成 dll 时随带生成的 lib 文件里的信息大多数情况可以完全从 dll 文件中萃取出来。
这种工具不难实现也有这样的工具。
quot 在下面留言中可以找到。
这个帖子讨论的问题已经没有什么意义了。
IMHO Posted by: Cloud 109 December 9 2006 05:58 PM 这个…… 好像 gcc 可以直接用 dll 不用带 lib 难道没人知道为什么楼下一直说 dll 一定要带一个 lib 而且根据标准的名字搅乱机制好像是可以直接从 dll 生成出 lib 的 Posted by: luoyi 108 December 9 2006 11:40 AM 一段时间没来看这里变成天涯杂谈了技术高也没什么了不起不懂技术也并不丢人.搞技术的就讨论一下技术能实作就实在出来看看你讽刺我我讽刺你的有什么意义电脑一关谁也不认识谁也也影响不了谁的生活.像云风这样能分享一下自己的所思所得并抽时间写出来的人还是值得鼓励的.尽管有的东西写的好有的东西有错误.别人说你好也未必从心里觉得你好别人说你不好未必从心里觉得你不好.一个人有好的品德宽容的心态获益最多的还是他自己. Posted by: xx 107 December 3 2006 02:16 PM 使用LoadLibrary和GetProcAddress 动态加载DLL不用Lib文件的吧呵呵 Posted by: 极光炫影 106 November 20 2006 12:11 AM eMule上搜索quotwindows source codequot就会出来了。
200400M大小。
nt4和Win2000的实现。
代码不完全。
但还是有不少东西可看的。
另外还有
开源的Wine和ReactOS项目可以参考。
madlax看看这个eMule的限速的实现。
也许对你有用。
http://www.newsmth.net/pc/pccon.phpid1904ampnid252546amporderamptid http://www.newsmth.net/pc/pccon.phpid1904ampnid253206amporderamptid http://www.newsmth.net/pc/pccon.phpid1904ampnid253207amporderamptid Posted by: 发条陈 105 November 11 2006 02:28 PM quotwindows 的源码可以去哪里下载quot 以前在电驴上好像可以搜索到一堆不过我没下载过。
Posted by: 星染流云 104 November 11 2006 08:42 AM 讨论点别的吧…… 客户端和服务端之间怎样测可用带宽比较合理呢TCP的协议和UDP的协议是否应该使用不同的办法 Posted by: madlax 103 November 9 2006 07:58 PM 那我们可以对Bennie说“ 你是电你是光你是唯一的奇迹我们全都爱你your are our ltagtSlt/agtuper ltagtBlt/agtennie ” Posted by: Anonymous 102 November 9 2006 07:56 PM 只有小孩子掐架才知道喊家属一起搀和糖你自己留着吃好了别吃出虫牙就好。
你又是CIH又是花花草草最后还要扮蛊惑仔叫你声白痴不过分。
记住 “白痴”一词是你引入的。
麻烦你告诉我“三省吾身”需要什么年龄省省自己先。
可以试着把自己知道的词贯通以下别胡乱蹦。
Posted by: Zenberg 101 November 9 2006 01:24 PM 我发个100帖。
哈哈 Posted by: sunway 100 November 9 2006 12:56 PM 现在知道喊妈妈是他先动手的 我当然承认不是善意的有加枪带棒所以这块糖是可以给你的当从我成了白痴这一点来看给你又有点冤。
至于enterprisebeing不知道到没到三省吾身的年龄 Posted by: Bennie 99 November 9 2006 12:15 PM 人不用你当成牛人也不会把你当白痴也没什么高不高明只是把自己明白的对方说错的纠正一下。
enterprisebeing早过了你关心的那些东西的年龄了 自己看看自己的话基本上也是你窜出来变成口水仗。
总是以已推人你会有更多事情不明白的 我身体很好 不累 我智商很低 不机灵。
Posted by: Zenberg 98 November 9 2006 10:38 AM 云风的方法不错应该就是这样了. Posted by: mike 97 November 9 2006 10:29 AM 呵呵这里没有什么陷阱。
我说的不明智的意思是证明口水战的对手是白痴并不能表明自己的高明之处我宁可先尊称对方是个牛人。
当然我还是可以继续看你在这抖机灵不过你不累么 Posted by: Bennie 96 November 9 2006 10:26 AM 如猎人般机警的Bennie想通过陷阱来证明某些人是把他归到白痴堆里证据就是他得到的答案“你真是个白痴”Bennie可能不知道像“你真是笨你真是无聊”之类的话并非一定要先把对方归类的那个“真是”并没有潜伏作用所以即使你把地点换成十三陵你得到的答案可能还是“你真是个白痴”。
不知道这是不是引入白痴说法得Bennie最关心的。
那我们可以对Bennie说“ 你是电你是光你是唯一的奇迹 我们全都爱你your are our Super Bennie” Posted by: Zenberg 95 November 9 2006 10:16 AM 一直不明白为什么有些人总喜欢把对方归到白痴的堆里要是我就不会做这么不明智的事情。
还有下面那些话是想看看某些人是不是除了大词以外还喜欢大话虽然我选择了风景现在还不错的八大处而结论也很明显了“真是个白痴” Posted by: Bennie 94 November 8 2006 09:11 PM 刚才又想了下纯粹是自找的。
自己写段程序解析 PE 头然后自己分配内存做重定位最多再处理下导入导出表就全部搞定了。
又没 windows 版本兼容问题。
把去年写的程序翻出来看了一下一共也没多长。
根本没必要追求合法的调用 windows api 来做这些事情。
不发言了昨天晚上该写完的程序现在还没收尾真是何苦。
Posted by: Cloud 93 November 8 2006 07:12 PM to mike 我有兴趣能否转贴一下。
不过不希望是自己解析 PE 这个我自己已经做过了。
另外希望在 windows 9x 和 nt 上都可以工作。
因为这是我们项目的必须要求。
Posted by: Cloud 92 November 8 2006 06:29 PM 先骂自己一下再挑起不同意见的话是不是不太厚道了。
:D 以我浅见做插件的人为了更流氓更应该研究的还是 shell 。
前几年想给 explore 做个插件自己用还是颇费下了点工夫研究的。
即使是耍流氓我见过的几个特别阴魂不散的流氓插件也是因为在 shell 上动了手脚。
不耍流氓的话基本上也就是在 shell 层做文章系统核心的东西能不碰还是尽量不碰的好。
Posted by: Cloud 91 November 8 2006 06:23 PM 小声问一下 windows 9x 的兼容问题怎么解决非反问 还有 windows 的源码可以去哪里下载或购买 10M 字节该有百万行了吧也不是小数目是需要花点时间看的。
读这个自然是值得的。
Posted by: Cloud 90 November 8 2006 06:04 PM Ldr开头的函数全部封装在ntdll里各位既然都这么牛逼调用个把的函数一下想必不是什么费劲事这片
代码最后一次修改也是上个世纪的事了还算得上是稳定至于说安不安全要看各位的身手了毕竟喝水也能噎死人。
Windows的核心
代码不过十来兆上下只有娱乐版的小编才会连Shell带外围程序放到一起攒上千万行的故事说事要是读一遍能死人做插件的大概都死绝了穷经皓首这事多虑了。
至于说读
代码上不了台面这事确实这年头会调用个把的Dll就能评价两句操作系统读源码多累还不如扎个式冒充个把蛊惑仔晃人快。
顺便鼓励一下Bennie南大楼的狱警们都盼着您老呢扛一蒲扇去八大处太远也太累还不如抄把小刀到中南海晃一下大家都省事。
嘿嘿真是个白痴。
Posted by: enterprisebeing 89 November 8 2006 05:37 PM 自己加载一个dll 很容易一般情况下只要实现段区映射还原和 base reloc 就可以了 没有什么好讨论的。
Posted by: Anonymous 88 November 8 2006 05:36 PM 文字对读的人有没有恶意是由写的人的感受来决定的如果读的人不同意那多是读的人心中的念头所至。
这种逻辑真是太绝妙了。
按照这个逻辑我应该砍掉云风的左手而云风不能喊痛也不能流血因为我认为他不该这样他如果非要这样那多半是他心中有什么恶念他的正确做法是应该把右手伸给我再砍砍掉后还是不能喊痛与流血而是要跳起来欢呼砍得好砍得好下面砍脚好吗因为他不这么做就是心中念头不好。
Posted by: Anonymous 87 November 8 2006 04:48 PM 可能性是一回事做出来是另一回事。
我指的是这个区别并无意贬低两种方式的任何一种。
我是偏向于实作的7 年前我没事找事去自己用汇编写重写了一遍 jpeg 的 decoder 当初就被很多网友痛骂一通最近一年自己从零实现 crt 就没想在网上招摇了我知道很多人会不屑。
如果有兴趣可以试试把一个 dll 做 base64 编码存在硬盘上写一个函数可以加载这个编码过的 dll 文件用用。
我说的是如果有兴趣没兴趣就算了。
不用去提什么立项外包。
有可能做出来的话open source 一把我相信很多人会喜欢的。
一行一行的跟踪windows运行时的机器码。
本不是件值得拿的上台面说的事我相信任何一个在 windows 下做过几年开发的人都干过。
windows 下许多 dll 文件我也用 ida pro 反编译读过一些关键地方的注释还留在我的一块老硬盘上。
我想这些是每个 windows 开发人员都值得做的事情。
根本不值得一提。
我承认我的一些回帖不是出于完全的善意但最少是中性的。
从中读出恶意来多是读的人心中的念头所至吧。
Posted by: Cloud 86 November 8 2006 02:37 PM to Cloud: --这个把quot
代码伪装成一个文本文件quot我想绝不是把 .dll 改掉后缀为 .txt 这种伪装。
我想至少也要做一次类似 base64 的编码才能看起来象文本文件一点吧。
如果能做到这一点自由加载 dll 的梦想就能实现了。
这个把quot
代码伪装成一个文本文件quot我想绝不是把 .dll 改掉后缀为 .txt 这种伪装。
我想至少也要做一次类似 base64 的编码才能看起来象文本文件一点吧。
如果能做到这一点自由加载 dll 的梦想就能实现了。
enterprisebeing 解释了“在这段
代码之后系统最终都会通过LdrpCreateDllSection对DLL文件进行处理LdrpCreateDllSection在读取DLL的时候有两个入口一个是路径另一个是文件句柄但文件句柄的参数并未公开暴露出来所以这个参数是个后门。
如果你使用自行编译的
代码当然可以用这个参数” “流式加载就是通过IO子系统进行加载” 你当然可以把dll进行base64编码再decode回来不就的了至于你到底想要如何“自由”的“按你希望的方式去”加载我智商低至今不知道你到底想怎么样。
--“enterprisebeing 毕竟是不同层次的人一想到要穷经皓首阅读上千万行的 windows 源码才能企及这样的层次 就感受到什么叫人生苦短。
” enterprisebeing 没有说他“穷经皓首阅读上千万行的 windows 源码”吧至于你怎么计算的大概只有你自己知道. 跟你工作同种的 Dunhill Hwang 说他以前为了弄明白windows的运作机制曾经一行一行的跟踪windows运行时的机器码也没见他喊什么人生苦短人现在过的也挺舒服的 --可以从 dll 加载方式来诟病 Windows对物理内存的利用率 enterprisebeing没有从dll加载方式来诟病 Windows对物理内存的利用率吧 你似乎忘记了你可以从dll上看出“美感”... --以上对 enterprisebeing 绝无不敬之意盖因大家面对的问题考虑的侧重点不同争论下去没有什么意义了 敬不敬看客们大概都心里有数争论下去确实没有意义. Posted by: Zenberg 85 November 8 2006 01:59 PM 1
VC 下才会有让 windows 开发新手困惑不解的动态链接 CRT 静态链接 CRT 多线程库单线程库 The reason is that different implementation of memory management in different NT CRT. 2 DLL 事实上和 EXE 文件一样同属 PE 格式的执行文件。
对于隐式的引用外部符号需要把外部符号所在的位置写在 PE 头上。
PE 加载器将从 PE 头上找到依赖的符号表并加载依赖的其它 DLL 文件。
NT is better than Linux in this case because M offer method to let user define the symbol to be exported. On Linux there are several methods but not very friendly. You can refer to one RH document quothow to write dynamic libraryquot for this topic. Posted by: wuyu 84 Novembe.
上一篇:
基于MapX的东海电缆管线地理信息系统开发
下一篇:
关于大学英语教学