INSIDE COM 最后一章例子 TANGRAM 编译笔记
VS2013项目下载地址: http://pan.baidu.com/s/1gemrBrl
注册并运行:
使用管理员权限. 运行 REGISTER.BAT. 然后运行 TANGRAM.EXE 即可.
注销组件:
使用管理员权限. 运行 UNREGISTER.BAT
总的步骤:
1.
首先构建解决方案. 把生成的DLL/EXE连同PDB一起放到一个目录中.
CANVAS.DLL + PDB
GDIWRLD.DLL + PDB
GLWRLD.DLL + PDB
MODEL.EXE/DLL + PDB
PROXY.DLL
TANGRAM.EXE + PDB
REGISTER.BAT
UNREGISTER.BAT
建议使用管理员权限操作. 因为涉及操作注册表.
REGISTER.BAT 用来注册组件. UNREGISTER.BAT 用来注销组件.
未解决的问题:
↑
见此页最下方. 有解决方案.
光使用 MODEL.DLL 的话, 没有问题. MODEL.EXE + PROXY.DLL 就会报错. 即 TANGRAM.EXE 的 GDIVISL.CPP 中 CTangramGdiVisual::Initialize, m_pIConnectionPoint->Advise 处报错 0x80040202 也就是 CONNECT_E_CANNOTCONNECT
并且, 把 PROXY.DLL 替换为 作者提供的 PROXY.DLL 就没有问题. (剩下的DLL和EXE都是我自己编译的).
经过调试 TANGRAM.EXE (同时附加到 MODEL.EXE 的进程), 发现 如果用我编译的 PROXY.DLL, 在 TANGRAM.EXE 进程中 CTangramModelEventSink::QueryInterface 返回 S_OK,
但到了 MODEL.EXE 进程中 就变成 E_NOINTERFACE 了. 很奇怪. 因为 PROXY.DLL 要负责进程间 RPC, 所以肯定是 PROXY.DLL 的问题. 我用 PE EXPLORER 查看了我编译的 PROXY.DLL 和作者提供的 PROXY.DLL
的区别 (或者用 dumpbin /imports /out:proxyimports.txt proxy.dll), 发现我的 PROXY.DLL 少了如下的 IMPORTS:
EF NdrSimpleStructMarshall
77 NdrConformantArrayBufferSize
ED NdrSimpleStructBufferSize
F1 NdrSimpleStructUnmarshall
F8 NdrStubInitialize
79 NdrConformantArrayMarshall
7B NdrConformantArrayUnmarshall
D7 NdrProxyGetBuffer
F7 NdrStubGetBuffer
D8 NdrProxyInitialize
D6 NdrProxyFreeBuffer
D9 NdrProxySendReceive
90 NdrConvert
我不知道这是不是导致问题的原因. 因为作者链接 PROXY.DLL 的时候用了 RPCNDR.LIB, 但是现在 RPCRT4.LIB 已经完全取代了 RPCNDR.LIB.
如果有哪位高手解决了这个问题. 请通知我! 万分感激!
INSIDE COM 最后一章 例子, VS2013 项目下载地址:
http://pan.baidu.com/s/1pJ8awcz
INSIDE COM 光盘源码下载地址:
http://pan.baidu.com/s/1dDG2vkd
2.
未完成:
↑
见此页最下方. 有解决方案.
Proxy.mak
搜索 VS 2013 Custom Build and Clean up Rule
https://msdn.microsoft.com/en-us/library/7s88b19e.aspx
https://social.msdn.microsoft.com/Forums/zh-CN/3f886933-e7dc-4b4f-bd34-9c9efa271471/custom-build-rules-in-vs2010?forum=msbuild
好像, 用 "项目属性 -> 配置属性 -> 自定义生成工具" 就可以解决这个问题
----------------------------------------------
笔记:
参考资料:
http://blog.csdn.net/lllxy/article/details/4277642
http://www.cnblogs.com/qrlozte/p/4173730.html
注: 有些解决方案很明显的编译链接错误就没有记录在这里.
1.
如果系统管理员权限设置的比较严格的话, 要用管理员权限打开 Tangram.exe
首先设置好项目依赖关系:
Canvas
Model 依赖 Canvas
GdiWrld 依赖 Model, Canvas
GLWrld 依赖 GdiWrld, Model, Canvas
Tangram 依赖 GdiWrld, GLWrld, Model, Canvas
除了 Tangram 以外, 其他项目都使用多字节字符集, Tangram 使用 UNICODE字符集 (原因见 5.4)
现在开始 设置 Canvas 项目:
1.1
打开 IDL 筛选器, 挨个把 IDL 文件移除重新添加(因为实际文件是大写名称, 这样才匹配, 主要是我强迫症), 查看 idl 文件的属性, 把 "配置属性 -> 常规 -> 项类型" 修改为 "MIDL 工具"
项目属性 -> 配置属性 -> MIDL -> 与 MkTypLib 兼容 -> 设为 "否"
参考: http://www.cnblogs.com/qrlozte/p/4995462.html
1.2
项目属性 -> 配置属性 -> MIDL -> 附加包含目录 -> 把 "IDL" 文件夹包含进来
项目属性 -> 配置属性 -> C/C++ -> 附加包含目录 -> 添加以下目录:
COMMON
SHARE
1.3
项目属性 -> 配置属性 -> MIDL -> 输出 -> 设置如下:
输出目录 : ..\SHARE
头文件 : %(Filename).h
DllData 文件 : %(Filename)_dlldata.c
IID 文件 : %(Filename).c
代理文件 : %(Filename)_P.c
1.4
把 解决方案资源管理器 中的 Share 筛选器中的 2个 .c 文件去掉, 把 SHARE 文件夹中
的 CANVAS_C.c, CANVAS_I.c 添加进来 (需要运行 MIDL 编译一次)
CANVAS_C.c - this ALWAYS GENERATED file contains the IIDs and CLSIDs, generated from CANVAS_C.IDL
CANVAS_I.c - this ALWAYS GENERATED file contains the IIDs and CLSIDs, generated from CANVAS_I.IDL
CANVAS_I_P.c - this ALWAYS GENERATED file contains the proxy stub code, generated from CANVAS_I.IDL
这个文件是单独用来生成 Proxy.dll 的, 不要包含到项目中!
参考: https://groups.google.com/d/topic/microsoft.public.platformsdk.com_ole/kTvbdBOrJpg
天朝局域网用户请看 cn.bing.com 的 CACHE: http://cncc.bingj.com/cache.aspx?q=CStdStubBuffer+release+4&d=4683049169070810&mkt=zh-CN&setlang=en-US&w=2RII6_hRiF9RmvKBYgFRwyJPrioAp5e7
因为只有 Model.EXE 需要 Proxy/Stub (与 Tangram.exe 进行通信), 所以实际上除了 Model 项目需要生成 Proxy.dll 之外, 其他项目都不需要生成 Proxy.dll
Model 项目生成 Proxy.dll 可以用 VS 中的命令行来实现. 参考 "Custom Build and Clean up"
作者已经提供了一个 Proxy.mak 来生成 Proxy.dll (见 Model 项目)
1.5
现在 Canvas 项目应该可以成功构建了
2.
Model 项目
2.1 - 2.3 参考 1.1 - 1.3
2.4
编译 idl 文件. 把生成的 EVENT_I.C, MODEL_C.C, MODEL_I.C 包括到 Share 筛选器中
2.5
把 CEnumConnectionPoints::CEnumConnectionPoints , CEnumConnections::CEnumConnections 中的 p 类型改为 CConnectionPointList::const_iterator
2.6
现在 Model 项目应该可以成功构建了
2.7
为了生成 Model.exe 以及对应的 Proxy.dll, 要做如下几件事
2.7.1
对 Proxy.mak 做了一些修改, 主要是几个 IDL 生成的 .c 文件都在 SHARE 文件夹里, 另外删掉了 rpcndr.lib
添加了 clean 逻辑 清理 Proxy.dll, Proxy.lib
2.7.2
生成 -> 配置管理器 -> 选择 解决方案为 LocalServer 配置, 并把除了 Model 以外的所有项目的配置都修改为 Debug
Model 配置为 LocalServer
可见在 Model 项目的预处理器中定义了 _OUTPROC_SERVER_ 宏. 并且配置为生成 MODEL.EXE + PROXY.DLL 而不是 MODEL.DLL
然后对 Model 按照 1.1 - 1.3 进行项目属性的修改.
2.7.3
Custom Build Steps and Build Events
参考: https://msdn.microsoft.com/en-us/library/e85wte0k.aspx
用 "项目属性 -> 配置属性 -> 自定义生成步骤" 添加命令行生成 Proxy.dll.
实际上作者是用的 "项目属性 -> 配置属性 -> 生成事件" 添加命令行 "nmake /f proxy.mak" 生成 Proxy.dll 的
我在 项目属性 -> 配置属性 -> 自定义生成步骤 中添加了清理的命令 "nmake /f proxy.mak clean"来删除生成的 Proxy.dll, Proxy.lib
3.
GdiWrld 项目
3.1 - 3.3 参考 1.1 - 1.3
3.4
把筛选器 Share 中的 Canvas_C.c, canvas_i.c 移除, 添加 SHARE 中的 CANVAS_C.C, CANVAS_I.C
编译 idl 文件. 把生成的 XXX_I.C, XXX_C.C 包括到 Share 筛选器中
再把 SHARE 中的 EVENT_I.C 也添加到 Share 筛选器中
3.5
现在 GdiWrld 项目应该可以成功构建了
4.
GLWrld 项目
4.1 - 4.3 参考 1.1 - 1.3
4.4
把作者提供的 GLAUX.LIB 和 GLAUX.H 放到项目文件夹中 (建议创建子文件夹 LIB)
并做好此项目对 GLAUX.H 以及 GLAUX.LIB 的引用
4.5
项目属性 -> 配置属性 -> 链接器 -> 高级 -> 映像具有安全异常处理程序 -> 设为 否 (为了与作者提供的 GLAUX.LIB 兼容)
4.6
好, 现在 GLWrld 项目应该可以成功构建了
5.
现在来配置 Tangram
5.1
项目属性 -> 配置属性 -> 常规 -> 字符集 -> 选择 UNICODE字符集
5.2
项目属性 -> 配置属性 -> C/C++ -> 附加包含目录 -> 添加以下目录:
COMMON
SHARE
5.3
尝试生成 Tangram, 可以看到 Registry.cpp 和 util.cpp 中有不少对 char* 报错的地方
主要是因为 MFC 现在默认只支持 UNICODE, 要编译非 UNICODE 的话必须下载非UNICODE的MFC库.
为了因为 Registry.cpp 和 util.cpp 是 前面 4 个项目都要用到的. 为了不影响另外4个项目.
删除 Tangram 项目的 Common 筛选器
复制 Registry.cpp 和 Util.cpp 以及其对应的头文件到 Tangram 目录下, 修改为 UNICODE 版本 (命名方面, 我加了 _U 后缀以示区别)
5.4
把 ConfigDlg.cpp 中 getFriendlyName 的 sprintf(szKeyBuf, "CLSID\\%s", szCLSID) ; 修改为:
wsprintf(szKeyBuf, _T("CLSID\\%s"), szCLSID) ;
类似的修改还有很多. 此处不一一列举. 总的原则就是把 char 用 TCHAR 或者 LPTSTR 或者 LPCTSTR 替换.
以及一些只能操作 char 的函数用 对应的 TCHAR 函数替换.
然后在必要的地方加上 _T() 宏
在 Registry_U.cpp 的 CLSIDtochar 中有比较重要的修改
5.5
...
生成:
CANVAS.DLL
MODEL.EXE + PROXY.DLL 或者 MODEL.DLL
GLWRLD.DLL
GDIWRLD.DLL
TANGRAM.EXE
关于 PROXY.DLL 报错 80040202 的问题:
https://social.msdn.microsoft.com/Forums/zh-CN/9d2ceb73-604e-418c-8e46-63e1baff4e2c/-inside-com-?forum=visualcpluszhchs#9d2ceb73-604e-418c-8e46-63e1baff4e2c
INSIDE COM 最后一章例子 TANGRAM 编译笔记的更多相关文章
- 第48章 MDK的编译过程及文件类型全解—零死角玩转STM32-F429系列
第48章 MDK的编译过程及文件类型全解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...
- 第三章 用SDK编译出第一个在Linux下的软件界面
第三章 用SDK编译出第一个在Linux下的软件界面 先创建一个工程目录“mkdir project1”,进入目录,创建main.cpp文件,编写代码如下: 代码内容暂时可以先不理解,先让程序跑起来再 ...
- 对ESP8266的例子进行编译时报错check_python_dependencies的问题的解决
尝试对ESP8266的例子进行编译时报错: make: *** 没有规则可制作目标"check_python_dependencies" 解决方法: 1.安装python pip包 ...
- 《TCP/IP详解卷1:协议》第2章 链路层-读书笔记
章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...
- LFS7.4编译笔记(3)
在第一部分,我们编译了一个工具链及临时系统,然后在第二部分我们chroot到/mnt/lfs下面,利用临时系统的工具编译了我们最终的LFS系统.不过此时,我们的LFS系统还是不完整的,因为我们还没有安 ...
- 第四章初始CSS3预习笔记
第四章 初始CSS3预习笔记 一: 1: 什么是CSS? 全称是层叠样式表;/通常又称为风格样式表,.他是用来进行网页风格设计的; 2:CSS的优势: 1>内容以表现分离,即使用u前面学习的HT ...
- Java程序设计(2021春)——第三章类的重用笔记与思考
Java程序设计(2021春)--第三章类的重用笔记与思考 本章概览: 3.1 类的继承(概念与语法) 3.2 Object类(在Java继承最顶层的类) 3.3 终结类和终结方法(只能拿来用,不可以 ...
- Java程序设计(2021春)——第四章接口与多态笔记与思考
Java程序设计(2021春)--第四章接口与多态笔记与思考 本章概览: 4.1 接口(接口的概念和声明接口.实现接口的语法) 4.2 类型转换 4.3 多态的概念 4.4 多态的应用 4.5 构造方 ...
- MRuby 编译笔记
专注于嵌入式脚本的MRuby在Windows下的编译笔记: 环境: OS: Windows 8.1, 使用 VS Express 2013 for Desktop. 材料: MRuby : 下载源码就 ...
随机推荐
- Python的包管理工具--PIP安装使用
最新安装方式 # wget https://bootstrap.pypa.io/get-pip.py # python get-pip.py // 使用该方式安装已经不再要求提前安装setuptoo ...
- ecshop退款订单原理分析
ecshop退款订单原理分析 时间:2013-04-12 23:41来源:www.chinab4c.com 作者:ecshop专家 点击:799 咨询qq:760868471咨询旺旺 ecshop退款 ...
- Yii源码阅读笔记(六)
组件(component),是Yii框架的基类,实现了属性.事件.行为三类功能,如果需要事件和行为的功能,需要继承该类,不需要可直接继承Object类: namespace yii\base; use ...
- breadth-first depth-first best-first
Computer Science An Overview _J. Glenn Brookshear _11th Edition For our example in Figure 11.7, we c ...
- Andrew Ng机器学习公开课笔记 -- Mixtures of Gaussians and the EM algorithm
网易公开课,第12,13课 notes,7a, 7b,8 从这章开始,介绍无监督的算法 对于无监督,当然首先想到k means, 最典型也最简单,有需要直接看7a的讲义 Mixtures of G ...
- JDBC 增删查改
public class MemberDaoImpl implements MemberDao { private Connection conn = null; public MemberDaoIm ...
- Oracle存储过程java 调用
1.nest表组合成结果集,然后以游标变量的形式返回 --创建类型 create or replace package mytest is -- Author : ADMINISTRATOR -- ...
- docker-compose bug
annot mount volume over existing file, file exists /var/lib/docker/aufs/mnt/0ac71fed1af802a4ecf4a93b ...
- python 输出乱码
在Python中有两种默认的字符串:str和unicode.在Python中一定要注意区分“Unicode字符串”和“unicode对象”的区别.后面所有的“unicode字符串”指的都是python ...
- 【SQL Server】左联接,右联接,内联接的比较
首先需要解释一下这几个联接的意思: left join(左联接): 返回包括左表中的所有记录和右表中联结字段相等的记录. right join(右联接): 返回包括右表中的所有记录和左表中联结字段相等 ...