COM组件入门(一)
近期须要用到COM组件的知识,看了看COM编程指南,感觉还不错。把我的学习心得记录下来。这是我依据教程写的demo
StopWatch接口实现部分,接口部分我的项目是动态库,主要源代码例如以下:
完整demo见:http://download.csdn.net/detail/davidsu33/7750101
stopwatch.h
#pragma once #include <Windows.h>
#include <MMSystem.h>
#include <Unknwn.h>
#include <WinBase.h>
#include "timer_i.h" class stopwatcher
{
public:
stopwatcher(void);
~stopwatcher(void);
}; class IStopWatch : public IUnknown
{
public:
//virtual unsigned long _stdcall Release() = 0;
virtual HRESULT _stdcall Start() = 0;
virtual HRESULT _stdcall ElaspedTime(float *elaspedtime) = 0;
}; class CStopWatch : public IStopWatch
{
public:
CStopWatch()
{
m_nRefValue = 0;
m_nFreq.QuadPart = 0;
QueryPerformanceFrequency(&m_nFreq);
AddRef();
}
public:
//virtual unsigned long _stdcall Release()
//{
// delete this;
// return 0;
//}; //创建相应的接口对象
virtual HRESULT STDMETHODCALLTYPE QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
{
if(riid == IID_IStopWatch)
{
*ppvObject = static_cast<IStopWatch*>(this);
return S_OK;
}
else if(riid == IID_IUnknown)
{
*ppvObject = static_cast<IUnknown*>(this);
return S_OK;
} *ppvObject = NULL;
return E_NOINTERFACE;
}; //添加引用
virtual ULONG STDMETHODCALLTYPE AddRef( void)
{
InterlockedIncrement(&m_nRefValue);
return m_nRefValue;
}; //解除引用
virtual ULONG STDMETHODCALLTYPE Release( void)
{
InterlockedDecrement(&m_nRefValue);
if(m_nRefValue == 0)
delete this;
return m_nRefValue;
}; virtual HRESULT _stdcall Start()
{
BOOL bOK = QueryPerformanceCounter(&m_nStartTime);
if(!bOK)
return S_FALSE;
return S_OK;
}; virtual HRESULT _stdcall ElaspedTime(float *elaspedtime)
{
LARGE_INTEGER nStopTime;
BOOL bOK = QueryPerformanceCounter(&nStopTime);
if(!bOK)
return S_FALSE; *elaspedtime = ((float)(nStopTime.QuadPart - m_nStartTime.QuadPart))/m_nFreq.QuadPart; return S_OK;
}; private:
LARGE_INTEGER m_nFreq;
LARGE_INTEGER m_nStartTime;
volatile unsigned long m_nRefValue;
}; //return IStopWatch interface object
extern "C" HRESULT _stdcall DllGetClassObject(REFCLSID rcsid, REFIID rid, LPVOID* lpvoid)
{
if(rcsid == CLSID_CStopWatch)
{
*lpvoid = static_cast<IStopWatch*>(new CStopWatch);
return S_OK;
} *lpvoid = NULL;
return CLASS_E_CLASSNOTAVAILABLE;
}
client的调用代码
#include "../stopwatch/stopwatcher.h"
#include "../stopwatch/timer_i.h" #include <iostream>
#include <cstring>
#include <cassert> #define TIMERDLL L"../Debug/stopwatch.dll"
#define PROCNAME "DllGetClassObject" typedef HRESULT (_stdcall* GETOBJFUNC)(REFCLSID , REFIID , LPVOID* ); using namespace std;
void trace(const char *str)
{
cout<<str<<endl;
} void trace(const string& s)
{
cout<<s.c_str()<<endl;
} HRESULT CreateInstance(void **p, HMODULE *rhMod)
{
HMODULE hMod = LoadLibrary(TIMERDLL);
if(!hMod)
return E_FAIL; GETOBJFUNC proc =
(GETOBJFUNC)GetProcAddress(hMod, PROCNAME); if(!proc)
return E_FAIL; *p = proc;
*rhMod = hMod; return S_OK;
} void FreeInstance(HMODULE hMod)
{
assert(FreeLibrary(hMod));
} void testInstance()
{
void *fptr = NULL;
HMODULE hMod = NULL;
HRESULT hr = CreateInstance(&fptr, &hMod);
if(FAILED(hr))
{
trace("CreateInstace failed");
return;
} GETOBJFUNC proc = (GETOBJFUNC)(fptr);
IUnknown *ptr = NULL; //首先得到类实例
//然后依据类实例得到IUnknown
//最后通过IUnknown调取QueryInterface接口来得到其子类的接口对象
//调用子类的接口对象
hr = proc(CLSID_CStopWatch, IID_IUnknown, (LPVOID*)&ptr);
if(FAILED(hr))
{
trace("GetObject failed");
return;
} if(!ptr)
{
trace("ptr is null");
return;
} IStopWatch *ptrSW = NULL;
hr = ptr->QueryInterface(IID_IStopWatch, (void**)&ptrSW);
assert(SUCCEEDED(hr)); hr = ptrSW->Start();
assert(SUCCEEDED(hr)); int m=0;
for(int i=0; i<10000000; ++i)
++m; float elaspedtime = 0;
hr = ptrSW->ElaspedTime(&elaspedtime);
assert(SUCCEEDED(hr)); cout<<"ElaspedTime:"<<elaspedtime<<endl; //释放对象本身
ptrSW->Release(); FreeInstance(hMod);
} int main(int argc, char *argv[])
{
testInstance();
getchar();
return 0;
}
COM组件入门(一)的更多相关文章
- highcharts图表组件入门教程:如何监听柱状图柱子点击事件动态更新当前数据点数值和所对应X轴刻度
highcharts图表组件入门教程:如何监听柱状图柱子点击事件动态更新当前数据点数值和所对应X轴刻度 作者:highcharts | 时间:2014-6-11 14:07:05 | [小 大] | ...
- Android Navigation 架构组件入门教程
Android Navigation 架构组件入门教程 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:https://www.cnblogs.com/cavalier-/p/1 ...
- Blazor 组件入门指南
翻译自 Waqas Anwar 2021年3月19日的文章 <A Beginner's Guide to Blazor Components> [1] Blazor 应用程序是组件的组合, ...
- JS组件入门
用React感觉component老好用了. 那如何用原生JS来模拟实现React中的component方法呢:http://huziketang.com/blog/posts/detail?post ...
- Android笔记二十七.Service组件入门(一).什么是Service?
转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.Service 1.Service简单介绍 Service为Android四大组件之中 ...
- es6+react.js组件入门初探
React是一个用于构建用户见面的javascript库. React主要用于构建UI,许多人认为React是MVC中的V(视图) React起源于Facebook的内部项目,用来架设Instagra ...
- bootstrap简单使用布局、栅格系统、modal标签页等常用组件入门
<!DOCTYPE html> <html> <head> <title>bootstrap</title> <!-- 引入boots ...
- 转:ECharts图表组件入门教程之Theme:ECharts图表的皮肤是什么?如何给图表换主题(皮肤)Theme?
一.什么是ECharts图表的皮肤(主题)? 针对这个问题我只能这样回答,ECharts图表的主题(皮肤)就犹如人的衣服一样,是用来衬托和渲染主体,使其变得更加美观好看的目的.你去过ECharts图表 ...
- vux Tabbar组件入门备忘大佬多指点
一.Tabbar引入及使用 1.新创建vue文件 2.在vue文件中添加插件 <template> <div> <tabbar style="position: ...
随机推荐
- Asp.net 身份验证方式?
[Forms 身份验证] 通过其可将没有通过身份验证的请求重定向到使用 HTTP 客户端重定向的 HTML 窗体的系统.用户提供凭据并提交该窗体.如果应用程序验证该请求,系统就会发出包含凭据或密钥的 ...
- Android项目中单实例数据库类,解决database is locked
一.数据库操作 package com.ping.db; import android.content.Context; import android.database.sqlite.SQLiteDa ...
- Windows执行打开文件命令
ShellExecute(NULL, "open", localFile.c_str(), NULL, NULL, SW_SHOW); 会调用该文件类型关联的 ...
- 使用Selenium+appium进行App测试
1. 启动安卓虚拟机.
- ajax给全局变量赋值问题
ajax给全局变量赋值问题 今天在做项目时,遇到了一个问题.我用的是ajax,要在$.ajax({里面给一个全局变量赋值,结果死活赋值不上,纠结了好半天,后来上网查了查,才知道,ajax默认是异步请求 ...
- 在VS2103环境中集成Doxygen工具
自己已将学习了两三次了吧,差不多这次该总结一下: Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,完全支持C.C++.Java.Objective-C和IDL语言,部分支持P ...
- 输出(test)
本题要求从输入的N个整数中查找给定的X.如果找到,输出X的位置(从0开始数):如果没有找到,输出“Not Found”. 输入格式: 输入在第1行中给出2个正整数N(<=20)和X,第2行给出N ...
- kerboros安装
尽管前面尝试了hadoop的simple认证方式,这种方法不是特别安全,在介绍一下hadoop的kerberos方式之前,下面我们尝试一下kerberos. 首先介绍一下Kerboros安装 OS 版 ...
- rm 注意
软连接ln -s lnfile file rm -rf lnfile只是删除lnfile ln -s lndir dir rm -rf lndir 删除链接 rm -rf lndir/删除目录下文件
- Hadoop学习记录(1)|伪分布安装
本文转载自向着梦想奋斗博客 Hadoop是什么? 适合大数据的分布式存储于计算平台 不适用小规模数据 作者:Doug Cutting 受Google三篇论文的启发 Hadoop核心项目 HDFS(Ha ...