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

最新文章

  1. 为革命保护视力 --- 给 Visual Studio 换颜色
  2. iOS开发中手机号码和价格金额有效性判断及特殊字符的限制
  3. JS学习之路
  4. Linux system 函数的一些注意事项
  5. 基于Spring的可扩展Schema进行开发自定义配置标签支持
  6. 问题记录:android.os.NetworkOnMainThreadException异常
  7. c++ algorithm 的用法
  8. linux学习笔记(3)-文件系统
  9. ES6数组去重
  10. TCP connect EADDRNOTAVAIL(99)错误原因分析
  11. Android view的测量及绘制
  12. Servlet 笔记-servlet实例
  13. Struts1基础、使用Struts实现登录、使用Struts HTML标签简化开发
  14. jquery cdn bootstrap静态资源库问题
  15. 03-java学习-基本数据类型-运算符-键盘接收用户输入
  16. C语言 · 字符串变换
  17. UDR rsync
  18. leetcode 136 Single Number, 260 Single Number III
  19. Spring Boot学习--项目启动时执行特定方法
  20. centoros 环境安装

热门文章

  1. CodeBlocks的汉化、主题美化及其调试功能的实现
  2. 暑假训练round 3 题解
  3. 【转】Html页面结构范例
  4. Ubuntu下关闭apache和mysql的开机启动
  5. DS实验题 Inversion
  6. 使用java代码,动态给TextView设置drawable
  7. placeholder属性实现text标签默认值提示用户
  8. memcached学习笔记2--安装及命令
  9. <?php set_time_limit(10);
  10. 统计学习方法笔记 -- Boosting方法