我今天竟然发现关于IntraWeb 在 EXE 和 DLL 模式下使用ADO的一个重大问题,希望和大家分享

Komacao 2003-10-29 11:51:53
我最近在用IntraWeb开发一个项目,开始是使用 EXE 方式开发调试,由于使用ADO连接 MS SQL-Server,因此参考了网上普遍认为的解决方案将 ServerController 的 ComInitialization 属性设置为 ciMultiThreaded。

今天我将部分完成的程序转化为 Dll 方式,打算放在IIS中看看效果,也是参照了网上的方案,将工程文件修改为DLL 模式(由于6.0.22的结构与5.X的结构不同,我手头的资料都是介绍的5.X的转换方法),编译通过后,放在我的本机IIS的虚拟目录中(已设置允许使用ISAPI)。在IE中输入地址后,满心期待着出现已经看过很多次的界面,结果,没有,出现错误提示“服务器内部错误”。我靠,这是怎么回事,是不是我转换的问题啊,仔细查看了半天,眼珠子都快瞪到显示器里了,最后的结论是:没有任何问题。虽然认为没有道理,但我还是重新新建了一个ISAPI工程,然后将原工程中的单元全部加进来,编译后放入IIS,打开IE,输入地址,故障依旧,我靠!!!

我开始怀疑可能是数据库连接的问题,开始以为是无法连接数据库,于是新建了一个新程序,做了一个简单的数据显示小程序,结果数据显示正常。我靠,数据库连接没问题啊。仔细想~~~,突然闪过一丝念头,刚才这个测试程序我好像没设置 ComInitialization 啊,怎么可以连的,立刻,改成 ciMultiThreaded 再试,哈,故障重现了,因为 ComInitialization 默认是 ciNone,这在 EXE 模式下是无法使用 ADO 的,在 DLL 模式下居然可以,又改成 ciNormal 再试,居然也没有问题。连忙把我的项目中的 ComInitialization 设置为 ciNormal,重新编译放入IIS,打开IE,输入地址,哈哈,我可爱的界面终于出来了~~~ :)

至此,得出结论:
1、EXE 模式下使用 ADO,ServerController 的 ComInitialization 属性应设置为 ciMultiThreaded 或 ciNormal。

2、DLL 模式下使用 ADO,ServerController 的 ComInitialization 属性应设置为 ciNormal 或 ciNone。

3、综合以上两点,ServerController 的 ComInitialization 属性建议设置为 ciNormal,两全其美,呵呵:)

但是,对于 ComInitialization 属性的这三个值我并没有很透彻的理解,他们究竟是什么含义,有什么区别,在 EXE 和 DLL 两种模式下为什么会出现上述的现象,不知有没有高人来解释一下呢!

我使用的开发环境为:Delphi 7 + IntraWeb 6.0.22 + Windows 2003 Server + IIS 6.0
...全文
138 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Komacao 2003-11-02
  • 打赏
  • 举报
回复
多谢halfdream(哈欠)!!! :)
halfdream 2003-10-30
  • 打赏
  • 举报
回复
这样理解应该差不多了:)
不过我这儿没有装D7,它一些具体实现的东西现在没分析.

不过有几点可以补充一下,
在IIS在处理请求的时候,你可以在进程观察器里面看看它有几个线程产生.
IIS调用你的DLL时候,不是直接调用,而通过DLLHOST.EXE调用(这样可以做到调到者与
你的DLL不在一个进程,你的DLL崩溃不会造成IIS进程崩溃)

Komacao 2003-10-30
  • 打赏
  • 举报
回复
halfdream(哈欠) 老哥,我当然知道ADO也是COM,所以才要设置 ComInitialization 属性啊。但现在问题是使用IntraWeb,所有的这些初始化都是被封装的,我就是不太理解这个属性的设置的确是和 EXE/DLL 模式有关,为什么会这样,才是我关心的。
Komacao 2003-10-30
  • 打赏
  • 举报
回复
我想我有点明白了,不过我有点表达不出来,应该是DLL本身就是处于一个线程中的,主线程应该是IIS,所以好像在DLL这个线程中就不能再初始化为多线程模式来调用ADO,因此 ciMultiThreaded 就会出错,而设为 ciNone,因为本来DLL就已经是在线程中了,所以也已经初始化过COM了,因此和 ciNormal 一样都可以正确调用 Com。而EXE因为本身就是主线程,所以 ciMultiThreaded 和 ciNormal 都可以使用线程调用 ADO,而 ciNone 因为主线程不会初始化COM,所以就无法调用ADO了。

我这样理解对不对啊。
horse_h 2003-10-30
  • 打赏
  • 举报
回复
up
zrwfx 2003-10-30
  • 打赏
  • 举报
回复
楼主,谢谢你,我也碰到同样的问题,我的提示是interface not supported,我的属性在
exe状态下设的就是ciMultiThreaded,后转为dll老提示interface not supported,我试试
,我用的版本是intraweb7.0.9
halfdream 2003-10-30
  • 打赏
  • 举报
回复
尽管你在EXE和DLL观察到的情况不同,得出上面的结论,
但事实上跟是不是EXE和DLL没什么关系.

确切说,区别在主线程与非主线程..
你使用EXE测试的时候,调用ADO的线程是用的主线程.
你使用DLL的时候,DLL里面调用ADO的线程是非主线程.

你可以做这两个测试验证.
1,做一个EXE型的COM组件(自动化对象,或者远程数据模块)都行..在远程方法里面
调用ADO.
2,做一个DLL,实现一个调用ADO的组件, EXE程序主线程里面调用它..




halfdream 2003-10-30
  • 打赏
  • 举报
回复
同使用EXE或者DLL根本无关:)
只是线程中使用COM的问题,关于几种线程模式的区别,你可以在网上找到具体细致的文档.

建议你先不要去改缺省的线程模式.
而是使用该用的
CoInitialize(nil);//或者 CoInitializeEx(...);
...(这儿你调用COM的代码)
CoUnInitialize;
halfdream 2003-10-30
  • 打赏
  • 举报
回复
这是使用COM的常识问题(ADO也是COM) :)
ToolBar工具栏控件的使用 动态建立主菜单选项 窗口界面的动态分隔条 动态设置选项卡页面 在标题栏中自定义按钮 窗体开合窗帘效果 Windows XP界面效果 实现OutLook滚动工具栏效果 在下拉列表框中显示树形视图 自定义系统的About项 修改系统级菜单 实现透明窗体效果 爆破特技窗体 只允许建立一次子窗体的MDI程序 从外部DLL中调用子窗口 新颖的资源管理器界面 如何生成半圆形窗口 制作字幕滚动窗体 详解Canvas生成渐变色窗口背景 WINAPM风格磁化窗口 软件封面的图片显示制作 实现图片的任意角度旋转 奇妙的拼图游戏 使用PaintBox控件制作画图程序 使用DrawGrid控件制作五子棋 多彩的数据报表 按压缩比将BMP转换为JPG 16位真彩转换到256色 调整图片的RGB对比度 实现图像的灰度级处理效果 3种像素历遍方法的比较和实现 实现屏幕拷贝 实现图像漫游 4种幕布式图像显示技巧 盘旋法实现9种滤镜效果 图形朦胧叠合显示技巧 给MDI主窗体增加背景 实现图像的淡入淡出显示 多媒体播放器 播放AVI文件 根据客户端IP地址获取计算机名 实现多线程IP和DomainName相互转换 Windows2000下的Popup发送功能 如何实现Ping操作 实现多线程共享探测 实现Windows95/98的I/O端口读写 收发电子邮件与监视网络服务器资源 使用WebBrower制作浏览器 可视化的Ping工具 使用IdMappedPortTCP进行端口映射 动态设置ODBC数据源 用ADO控件打开Access数据库 DBGrid中的记录到Html页面的转换 在DBGrid中实现任意方向查找 在DBGrid中通过动态下拉列表查找记录 用DBGrid组件制作下拉列表形式的提示框 利用书签处理DBGrid中的多个记录 将ComboBox中的内容直接拖放到DBGrid里 如何在DBGrid里放置图标 DBGrid控件精彩组合 DBChart图表控件的使用 在StringGrid组件中显示查询结果 使用流对象(Tstream)实现数据表中Tmemo字段的显示 如何动态建立SQLServer ODBC SQL浏览器 在SQL查询中使用动态参数 事务工作原理 标准/模糊查询 筛选数据 数据字典查看器 TDecisionGraph决策组件的使用 明细表(Master/Detail)结构 像处理文本资料一样处理数据表中的信息 远程数据库登录 远程数据库的离线处理 在远程数据库中实现主从表关系 动态设置远程数据库的查询参数 在远程数据库中计算统计值 多线程与数据库 使用远程存储过程 数据模块的同步显示 建立Web服务的数据提供端 建立Web服务的数据访问端 开发WebSnap数据库程序 建立ActiveForm数据浏览 建立数据查询WebServices服务器端 数据查询Web服务客户端开发 基于WAP的手机无线应用 建立基本Web数据库服务器应用 建立类型库编辑DataSnap服务端 建立查询条件Web数据库服务器应用 建立基本MTS服务端 建立MTS数据访问客户端 建立IntraWeb数据浏览 将程序图标设置到Windows系统托盘 取得和修改文件的创建和修改日期 通过流式数据实现文件分割与合并 实现指定扩展名文件和相应程序的关联 获取汉字拼音的首字母 监视剪贴板 在IE工具栏上增加一个按钮图标 软件注册机制的建立 复活节彩蛋的制作 SkinEngine控件——XP换肤 ActionList——应用程序通用功能列表 OleContainer——OLE容器 将程序项设置到控制面板 艺术化排列桌面图标 Delphi中的ini文件的读写 建立键盘鼠标动作记录与回放 实现指定目录下的文件查询 实现对系统的操作监视 系统级热键的实现 检测NumLock、Insert、CapsLock、ScrollLock键的状态

1,594

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧