Dllimport时要注意的一些问题,特别是工作在64位IIS7的必看。

编程技术  /  houtizong 发布于 2年前   99

开篇声明:存在必是合理,请不要白费力气和我讨论这个模式的必要性。

最近要在一个项目中把大部分代码都封装到标准C的DLL中,asp.net的部分仅仅做 [Dllimport "xxxxx" ],输入输出接收和传送字符串等这些最简单的动作。


这就需要考虑几个问题:虚拟主机支持、IIS6的兼容性、IIS7-32位模式兼容性、IIS7-64位模式兼容性、32位本地桌面兼容性、64位本地桌面兼容性。

以及:既然是WEB程序,肯定就关系到数据库的使用,既然代码都是用C++(使用标准C++,不是托管C++)编写,那么ADO.NET是肯定不能使用的了,所以选择了SQLITE(原因不在本话题,省略过)。

幸好是选择了SQLITE,才会发现这个问题,要不然如果直接使用ADO加载ACCESS或SQLSERVER的话,将来需要更换数据库时才发现问题就惨了。

一开始,我直接使用SQLITE提供的现成DLL:SQLITE3.DLL,本地桌面测试通过,结构是这样的:

Dllimport时要注意的一些问题,特别是工作在64位IIS7的必看。 

可是在IIS中使用的时候,问题出现了:“找不到所需的库文件:SQLITE3.DLL”。怎么会找不到呢? 都放在BIN目录中,我的年龄还不至于到了看眼花的程度,但是本着敬业的态度,还是到医院做了一番检查,医生和仪器都一致同意:“您的视力没有问题。”。确定不是我眼睛有毛病后,想到是不是因为这是试用版WINDOWS做了限制,但是本着敬业的态度,于是我打电话给鲍尔默:“老鲍,试用版WINDOWS会不会在IIS中做了什么限制的手脚?”,老鲍说:“你放心,绝对没有限制,和正式版一模一样。但是我建议你购买正式版WINDOWS,可以享受到7*24小时的电话技术支持服务、免费更新服务……”,老鲍说WINDOWS没有问题,那就肯定没有问题。那么问题出在哪里呢?这时候,有个电话找我:“为什么你昨天给我的那个ISO文件我刻盘了不能安装?”,我问:“你是怎么刻的?详细道来。”,电话那边说:“我把你给我的文件直接拖放到刻录机中,让他自己自动刻录……”,一听就来气了:“镜像文件居然让你这样刻录,亏你还是计算机研究生,你趁早改行回家挑粪去算了。顺便叫你老师和你一起去挑粪,这种弱智问题不要问我了,问你校长去。”。挂了电话。MD,这年头学校都教出什么货色来,还计算机研究生呢,刻个镜像文件都不会……,自己嘟哝到一半,忽然灵光一闪:“镜像文件!”,恍然大悟,想起来了,BIN中的东西实际上都是镜像而已,真正执行的时候,是把这些文件复制到系统专用目录中去执行的,并不是直接执行BIN目录中的文件。我在C#中仅仅是DLLIMPORT  “CPP.DLL”,所以IIS当然就是仅仅只把CPP.DLL复制到系统目录中去了,而C++中的算法是“加载当前目录中的SQLITE3.DLL”,这时候SQLITE3.DLL仍然只是在BIN目录中,当然就找不到了。

知道了原因,马上就闪现了2个解决方案:1 让IIS把SQLITE3.DLL也加载就行了。 2 把SQLITE3.DLL封装到CPP.DLL中。

两个方案应该用哪种呢?直觉告诉我,应该用第二种,因为方案1为系统算法带来了多余的行为,对于C#这一方来说,它仅仅是“中间人”的角色, C#负责做的事情是在逻辑层面(CPP.DLL)和输入输出层面(IIS或者WINFORM)建立一个沟通渠道,它没有理由跨过逻辑层而直接与数据库层(SQLITE.DLL)打交道,即使仅仅是加载,而没有参与真正读取数据库也不行,因为它没有理由去加载一个它“不认识”的家伙。那就这么定了,把SQLITE.DLL集成到CPP.DLL中,让系统只加载一个WIN32的DLL,这样一来也减少了错误发生的机会:要么全部出错,要么就不会出错。

说得轻巧,做起来难,怎么合并?用记事本打开它们两个,然后把内容拼接到一起,再另存为“CPP.DLL”?我可不是研究生,这么高级的操作我不会。还是想别的办法吧,幸好,SQLITE是开源的,并且免费使用在包括商用在内的任何领域。到WWW.SQLITE.ORG去下载了源码,就三个文件,一个sqlite3.c文件,一个sqlite3.h文件,还有一个sqlite3_ext.h(这个文件干什么用的也没有去研究,总之就是多余的,可以删掉了)文件。

把两个文件加载到c++的源码中,去掉原先加载的sqlite3.lib, 编译,得到新的cpp.dll,果然容量增大了380多K,这次肯定行了。把IIS中BIN文件夹里面的东西删掉,再扔这个新的cpp.dll进去,测试运行,成功!此时也不再需要依赖sqlit3.dll了。此时的架构是这样的:

 

Dllimport时要注意的一些问题,特别是工作在64位IIS7的必看。 

 

通常,从一个想法的产生到能够真正实现出来,不知道要经过多少次调试、查错、论证……,哪怕它仅仅是一个“Hellow World!”也不能逃过这些劫难,而这次,一切却如此顺利,所以可以说,这种幸运的机会是少之又少的,完全取决于你上辈子积蓄的阴德。

黑暗的旧社会终于被解放了。新中国万岁!

可是,新中国成立10多年后,依然有了一次整体上10多年的社会事件,而那次事件的某些后遗情况也直接影响到我们2008年的今天。

此时,有一些Buger们,正潜藏在DLL的某个阴暗角落里,在等待着反清复明的机会:“下个月乾隆要来纽约,我们先埋伏着,只要他一上到世贸大厦的一半,十四弟的那几架波音787自然会启动,一切等待和大人的指示,别的事情一概不管,以免走漏风声。特别要当心那个叫纪晓岚的。”。

一切都运行得井井有条。dll在windows2003中的测试的过程居然如此风平浪静,似乎要预示着一场毁天灭地的灾难即将淹没庞贝城。

一天的工作结束,不结束也不行了,眼皮都打架了。记录完版本开发进程,备份了代码到网上去,重启电脑,切换到VISTA去,准备洗澡。

说到这里,顺便给大家一个提示:开发工作用的电脑,最好是有两块硬盘,有条件的组RAID1,不想组的也要做个定时同步计划,没有两块硬盘的就应该把项目备份到网上私人空间里或者U盘里,要不然,会在将来某个时刻死得很惨。

我装有两个系统,一个是32位2003,一个是64位VISTA,常用的是VISTA,2003只在必要的时候才使用(例如这次开发这个东西,为了先保证32位平台,就先在2003中测试开发)。因为切换一次系统就要合并一次QQ记录的关系,所以干脆就不在2003里面开QQ了。 洗澡归来,打开VISTA,上QQ看有没有哪个妞来请我出去做秘密郊游,果然有,约好时间,准备睡觉,为明天的郊游做好休息,睡前为了再欣赏一遍今天的劳动成果,打开chrome,在地址栏输入127.0.0.1/using_cpp.aspx,回车。

平时我看电视都是喜欢看新闻频道,一来关心国家大事,二来经常可以看到世界各地的美人。此时传来东央电视台的播报 :"据一位不愿意透露姓名的FBI官员称,当年911事件另有说法:5架波音787客机的64位导航系统未将对象引用设置到对象的实例,导致同时启动了自动寻找地面重点对象的程序"。

 

我的眼前一黑, 完了,明天还怎么和紫嫣妹妹去郊游,想到可能是因为人困了,眼睛出毛病,本着敬业态度,我连夜跑去医院做了眼睛检查,医生和仪器再次确认:“您的视力没有问题”。难道是因为VISTA是30天试用版的关系,我再次接通鲍尔默的电话:“老鲍……”,还没等我问,他就先回答了:“上次你挂电话那么快,我还没有来得及说,不光是WINDOWS2003,就连VISTA的试用版也是和正式版完全一致,不会存在任何使用限制,此外,我强烈建议你购买我们的VISTA系统,你可以享受到7*24小时的……”,算了,不睡了。

我打开IIS7控制台,32位模式、64位模式,经典模式、集成模式、 总共 4*4=16种设置方案,全都无效。重启换回WINDOWS2003,32位模式IIS下运行工作正常,再换回VISTA的64位IIS,工作失败,再试试64位桌面程序加载情况:失败。

可能是编译器问题吧,以前就听说过同是一块cpu,32位模式下编译的东西是不能直接在64位下面运行的这种类似情况,打开VISTA下的VC2008,把cpp.dll重新编译为64位,然后把C#代码先复制到asp.net文件中,让它自动识别工作模式,结果是失败。再在64位环境下编译32位版本cpp.dll,再设置IIS7工作于32位模式,还是失败。死定了!

5小时的详细调试过程省略100万字……

把问题最小化,省略所有的多余代码,事件的起因找到了:

extern  " C "  _declspec(dllexport) char *  ReadData( )
{
    std::string str
=   " abcd " ;//实际工作中,这个abcd是由数据库产生的
    
char *  temp  =  strdup(str.c_str());
    
return  temp;
    
// delete temp;
}

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客