惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
Jina AI
Jina AI
博客园_首页
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Forbes - Security
Forbes - Security
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
N
News | PayPal Newsroom
S
Security Archives - TechRepublic
量子位
Cisco Talos Blog
Cisco Talos Blog
V
V2EX
C
Cisco Blogs
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
Scott Helme
Scott Helme
S
Securelist
Security Latest
Security Latest
爱范儿
爱范儿
TaoSecurity Blog
TaoSecurity Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
I
Intezer
L
LINUX DO - 最新话题
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
月光博客
月光博客
T
Tailwind CSS Blog
Cloudbric
Cloudbric
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
Kaspersky official blog
D
DataBreaches.Net
博客园 - 【当耐特】
有赞技术团队
有赞技术团队

博客园 - 跌跌撞撞

CArchive的一个经验 设计Client 学习反汇编记录 299错误解决记录 23日记录 用ADO访问存储过程的参数问题 SDKMisc的一个小错误 年初一作诗 走出GDI 总是在最求效率。 - 跌跌撞撞 新感 下来做什么呢 开发目录包括的内容 太可爱的小小播放器 lucene的设计 上海感觉 写一点感想 项目管理的成功秘密(翻译) 昨天看书的心得
加载COM的方式
跌跌撞撞 · 2008-11-19 · via 博客园 - 跌跌撞撞

通常我们都是使用CoCreateInstance或CoGetClassObject获得接口,再通过接口访问他的成员方法。在C++支持下,从来不会有任何问题。但是如果使用Win32模式,纯粹C风格编程,就会出现问题了。
通过研究我发现其实上述访问方式本身就存在问题。标准的访问方式,如D3D一样,接口的初始化必须在Com提供的API基础上完成。COM设计者需要提供一个API,像DLL的导出函数一样,供给外部程序调用。

具体设计:
下面是一个gdi扩展函数库gdiex,GdiexCreate就是创建接口的一个函数,如同Direct3DCreate9一样,调用这个函数可以立刻创建一个接口指针。
在COM内部设计导出函数,如:
HRESULT WINAPI GdiexCreate(LPVOID *lplpGdiex)
{
 HRESULT hr;
 ISaveDDCtl * pCtrl = NULL;

 hr = CoCreateInstance( CLSID_SaveDDCtl, NULL, CLSCTX_SERVER, IID_ISaveDDCtl, (void**) &pCtrl);

 if(FAILED(hr))
 {
  MessageBox(NULL, "GdiexCreate Failed!", "gdiexPS", MB_OK|MB_ICONSTOP);
  return hr;
 }

 *lplpGdiex = (LPVOID) pCtrl;

 return S_OK;
}
该函数可以放在主要cpp文件中。
在导出的头文件(gdiex.h)中作出声明:
HRESULT WINAPI GdiexCreate(LPVOID *lplpGdiex);

只要不重新生成COM,这个头文件中都会包含该API。

下来在gdiex.def增加这个API名字,以便外部访问。
EXPORTS
 DllCanUnloadNow  PRIVATE
 DllGetClassObject PRIVATE
 DllRegisterServer PRIVATE
 DllUnregisterServer PRIVATE
    GdiexCreate
   
调用的时候,只需要在工程中包含gdiex.h, 输入gdiex.lib,就可以调用到这个API
ISaveDDCtl * pCtl = NULL;
CoInitialize( NULL );

hr = GdiexCreate( (LPVOID*) &pCtl );
if(FAILED( hr )) {
 return hr;
}
... ...
GdiexFree( (LPVOID) &pCtl );    //gdiex释放API,在gdiex模块中定义。
CoUninitialize();

就是这样,调用者没有出现多余的访问,就可以获得接口。而且C/C++都可以很好的工作。

15:06 2008-11-19 liz