COM组件 ATL的创建和调用
参考:
- VS: VS2015创建ATL
- VC:VC6.0创建ATL
实例
1. 包含两个接口: Student,Teacher
2. Student接口包含5个函数(方法)
3. Teacher接口包含3个函数(方法)
创建COM组件 ATL
1. 在接口对象文件("Student.h")添加以下代码:
// Student.h : CStudent 的声明#pragma once
#include "resource.h" // 主符号#include <vector>
#include "VsAtlProjectOne_i.h"#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
#endifusing namespace ATL;
using namespace std;struct Student
{CHAR *pName;ULONG unNO;UINT unAge;CHAR *pAddress;
};// CStudentclass ATL_NO_VTABLE CStudent :public CComObjectRootEx<CComSingleThreadModel>,public CComCoClass<CStudent, &CLSID_Student>,public IDispatchImpl<IStudent, &IID_IStudent, &LIBID_VsAtlProjectOneLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:CStudent(){}DECLARE_REGISTRY_RESOURCEID(IDR_STUDENT)BEGIN_COM_MAP(CStudent)COM_INTERFACE_ENTRY(IStudent)COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()DECLARE_PROTECT_FINAL_CONSTRUCT()HRESULT FinalConstruct(){return S_OK;}void FinalRelease(){}private://学生数据vector<Student> m_vStudent;public://增加学生信息STDMETHOD(AddStuInfo)(CHAR* pStuName, ULONG unStuNO, UINT unStuAge, CHAR *pAddress);//通过姓名获取年龄STDMETHOD(GetStuAgeFromName)(CHAR* pStuName, UINT* pStuAge);//通过姓名获取学号STDMETHOD(GetStuNOFromName)(CHAR* pStuName, UINT* pnStuNO);//通过姓名获取地址STDMETHOD(GetStuAddressFromName)(CHAR* pStuName, CHAR** pnStuAddress);//获取学生总数STDMETHOD(GetStuNumber)(UINT* punStuNumber);
};OBJECT_ENTRY_AUTO(__uuidof(Student), CStudent)
2. 在接口对象文件("Student.cpp")添加以下代码:
// Student.cpp : CStudent 的实现#include "stdafx.h"
#include "Student.h"// CStudent//增加学生信息
STDMETHODIMP CStudent::AddStuInfo(CHAR* pStuName, ULONG unStuNO, UINT unStuAge, CHAR *pAddress)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());Student StudentInst;StudentInst.pName = pStuName;StudentInst.unNO = unStuNO;StudentInst.unAge = unStuAge;StudentInst.pAddress = pAddress;m_vStudent.push_back(StudentInst);return S_OK;
}//通过姓名获取年龄
STDMETHODIMP CStudent::GetStuAgeFromName(CHAR* pStuName, UINT* pStuAge)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());vector<Student>::iterator itStu;for (itStu = m_vStudent.begin(); itStu != m_vStudent.end(); itStu++){if (strcmp((*itStu).pName, pStuName) == 0){*pStuAge = (*itStu).unAge;break;}}return S_OK;
}//通过姓名获取学号
STDMETHODIMP CStudent::GetStuNOFromName(CHAR* pStuName, UINT* pnStuNO)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());vector<Student>::iterator itStu;for (itStu = m_vStudent.begin(); itStu != m_vStudent.end(); itStu++){if (strcmp((*itStu).pName, pStuName) == 0){*pnStuNO = (*itStu).unNO;break;}}return S_OK;
}//通过姓名获取地址
STDMETHODIMP CStudent::GetStuAddressFromName(CHAR* pStuName, CHAR** pnStuAddress)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());vector<Student>::iterator itStu;for (itStu = m_vStudent.begin(); itStu != m_vStudent.end(); itStu++){if (strcmp((*itStu).pName, pStuName) == 0){*pnStuAddress = (*itStu).pAddress;break;}}return S_OK;
}//获取学生总数
STDMETHODIMP CStudent::GetStuNumber(UINT* punStuNumber)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());*punStuNumber = m_vStudent.size();return S_OK;
}
3. 在接口对象文件("Teacher.h")添加以下代码:
// Teacher.h : CTeacher 的声明#pragma once
#include "resource.h" // 主符号#include <vector>#include "VsAtlProjectOne_i.h"struct Teacher
{CHAR *pName;ULONG unNO;
};#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
#endifusing namespace ATL;
using namespace std;// CTeacherclass ATL_NO_VTABLE CTeacher :public CComObjectRootEx<CComSingleThreadModel>,public CComCoClass<CTeacher, &CLSID_Teacher>,public IDispatchImpl<ITeacher, &IID_ITeacher, &LIBID_VsAtlProjectOneLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:CTeacher(){}DECLARE_REGISTRY_RESOURCEID(IDR_TEACHER)BEGIN_COM_MAP(CTeacher)COM_INTERFACE_ENTRY(ITeacher)COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()DECLARE_PROTECT_FINAL_CONSTRUCT()HRESULT FinalConstruct(){return S_OK;}void FinalRelease(){}private://老师信息vector<Teacher> m_vTeacher;public://增加老师信息STDMETHOD(AddTeacherInfo)(CHAR* pTeaName, UINT unTeaNO);//通过姓名工号STDMETHOD(GetTeaNOFromName)(CHAR* pTeaName, ULONG* unTeaNO);//获取老师总数STDMETHOD(GetTeaNumber)(UINT* punTeaNumber);
};OBJECT_ENTRY_AUTO(__uuidof(Teacher), CTeacher)
4. 在接口对象文件("Teacher.cpp")添加以下代码:
// Teacher.cpp : CTeacher 的实现#include "stdafx.h"
#include "Teacher.h"// CTeacher//增加老师信息
STDMETHODIMP CTeacher::AddTeacherInfo(CHAR* pTeaName, UINT unTeaNO)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());Teacher TeacherInst;TeacherInst.pName = pTeaName;TeacherInst.unNO = unTeaNO;m_vTeacher.push_back(TeacherInst);return S_OK;
}//通过姓名工号
STDMETHODIMP CTeacher::GetTeaNOFromName(CHAR* pTeaName, ULONG* unTeaNO)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());vector<Teacher>::iterator itTea;for (itTea = m_vTeacher.begin(); itTea != m_vTeacher.end(); itTea++){if (strcmp((*itTea).pName, pTeaName) == 0){*unTeaNO = (*itTea).unNO;break;}}return S_OK;
}//获取老师总数
STDMETHODIMP CTeacher::GetTeaNumber(UINT* punTeaNumber)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());*punTeaNumber = m_vTeacher.size();return S_OK;
}
5. 接口对外声明文件("VsAtlProjectOne.idl")添加以下代码:
// VsAtlProjectOne.idl : VsAtlProjectOne的 IDL 源
//// 此文件将由 MIDL 工具处理以
// 产生类型库(VsAtlProjectOne.tlb)和封送处理代码。import "oaidl.idl";
import "ocidl.idl";[object,uuid(EA00B97F-C817-43B6-94A2-E3B52CAC9610),dual,nonextensible,pointer_default(unique)
]
interface IStudent : IDispatch{[id(1)] HRESULT AddStuInfo([in] CHAR* pStuName, [in] ULONG unStuNO, [in] UINT unStuAge, [in] CHAR* pStuAddress);[id(2)] HRESULT GetStuAgeFromName([in] CHAR* pStuName, UINT* pStuAge);[id(3)] HRESULT GetStuNOFromName([in] CHAR* pStuName, UINT* pnStuNO);[id(4)] HRESULT GetStuAddressFromName([in] CHAR* pStuName, CHAR** pnStuAddress);[id(5)] HRESULT GetStuNumber([out] UINT* punStuNumber);
};
[object,uuid(B6E8E710-37A4-49BD-9CD9-56313DF7AA59),dual,nonextensible,pointer_default(unique)
]
interface ITeacher : IDispatch{[id(1)] HRESULT AddTeacherInfo([in] CHAR* pTeaName, [in] UINT unTeaNO);[id(2)] HRESULT GetTeaNOFromName([in] CHAR* pTeaName, [out] ULONG* unTeaNO);[id(3)] HRESULT GetTeaNumber([out] UINT* punTeaNumber);
};
[uuid(284DA5FE-71F9-4D34-8656-EF28201C766C),version(1.0),
]
library VsAtlProjectOneLib
{importlib("stdole2.tlb");[uuid(44DFFA13-CA7A-447C-960C-1676644028A0) ]coclass Student{[default] interface IStudent;};[uuid(8F193EA0-0E18-415D-9F46-DCF3D82D5E1F) ]coclass Teacher{[default] interface ITeacher;};
};import "shobjidl.idl";
调用COM组件 ATL
#include "stdAfx.h"
#include "TestAtl.h"//导入组件
//将"VsAtlProjectOne.dll" 放到目录 "C:\Windows\System32"
#import "VsAtlProjectOne.dll" no_namespace //如果不知道命名空间,需要加上 no_namespacevoid TestAtl()
{//初始化组件::CoInitialize(NULL);//获取组件接口的SID(通过属性)CLSID sidStudent;HRESULT hStudent = ::CLSIDFromProgID(L"VsAtlProjectOne.Student", &sidStudent);if (hStudent == S_OK){//获取接口对象(通过接口ID)IStudent *pStudent(NULL);hStudent = ::CoCreateInstance(sidStudent, NULL, CLSCTX_INPROC_SERVER, __uuidof(IStudent), (LPVOID *)&pStudent);//调用接口函数(通过接口对象)if (hStudent == S_OK){hStudent = pStudent->AddStuInfo("赵四", 123456789, 88, "四川.长春");if (hStudent == S_OK){TRACE("\n查找学生成功\n");}else{TRACE("\n增加学生失败\n");return;}hStudent = pStudent->AddStuInfo("刘能", 168, 18, "吉林.长春");if (hStudent == S_OK){TRACE("\n增加学生成功\n");}else{TRACE("\n增加学生失败\n");return;}hStudent = pStudent->AddStuInfo("杨晓燕", 288, 28, "贵州.贵阳");if (hStudent == S_OK){TRACE("\n增加学生成功\n");}else{TRACE("\n增加学生失败\n");return;}hStudent = pStudent->AddStuInfo("王大拿", 888, 99, "辽宁.大连");if (hStudent == S_OK){TRACE("\n增加学生成功\n");}else{TRACE("\n增加学生失败\n");return;}hStudent = pStudent->AddStuInfo("谢广坤", 22222, 90, "辽宁.大连");if (hStudent == S_OK){TRACE("\n增加学生成功\n");}else{TRACE("\n增加学生失败\n");return;}UINT unStuAge = 0;hStudent = pStudent->GetStuAgeFromName("杨晓燕", &unStuAge);if (hStudent == S_OK){TRACE("\n查找学生成功\n");}else{TRACE("\n查找学生失败\n");return;}UINT unStuNO = 0;hStudent = pStudent->GetStuNOFromName("王大拿", &unStuNO);if (hStudent == S_OK){TRACE("\n查找学生成功\n");}else{TRACE("\n查找学生失败\n");return;}CHAR *pStuAddress;hStudent = pStudent->GetStuAddressFromName("刘能", &pStuAddress);if (hStudent == S_OK){TRACE("\n查找学生成功\n");}else{TRACE("\n查找学生失败\n");return;}UINT unStuNumber(0);hStudent = pStudent->GetStuNumber(&unStuNumber);if (hStudent == S_OK){TRACE("\n查找学生成功\n");}else{TRACE("\n查找学生失败\n");return;}}}CLSID sidTeacher;HRESULT hTeacher = ::CLSIDFromProgID(L"VsAtlProjectOne.Teacher", &sidTeacher);if (hTeacher == S_OK){ITeacher *pTeacher;hTeacher = ::CoCreateInstance(sidTeacher, NULL, CLSCTX_INPROC_SERVER, __uuidof(ITeacher), (LPVOID *)&pTeacher);if (hTeacher == S_OK){hTeacher = pTeacher->AddTeacherInfo("严守一", 123456);if (hTeacher == S_OK){TRACE("\n添加老师成功\n");}else{TRACE("\n添加老师失败\n");}hTeacher = pTeacher->AddTeacherInfo("费默", 998);if (hTeacher == S_OK){TRACE("\n添加老师成功\n");}else{TRACE("\n添加老师失败\n");}hTeacher = pTeacher->AddTeacherInfo("于文娟", 1314);if (hTeacher == S_OK){TRACE("\n添加老师成功\n");}else{TRACE("\n添加老师失败\n");}ULONG unTeaNO(0);hTeacher = pTeacher->GetTeaNOFromName("费默", &unTeaNO);if (hTeacher == S_OK){TRACE("\n查找老师成功\n");}else{TRACE("\n查找老师失败\n");}UINT unTeaNumber(0);hStudent = pTeacher->GetTeaNumber(&unTeaNumber);if (hStudent == S_OK){TRACE("\n查找老师成功\n");}else{TRACE("\n查找老师失败\n");return;}}}//释放线程加载的组件,卸载线程所有的DLL::CoUninitialize();
}
COM组件 ATL的创建和调用相关推荐
- 使用vue-cli创建Vue工程化项目及单文件组件的创建和调用
文章目录 1. Vue 单文件组件的优势 2. cli 创建 Vue 工程项目 3. 单文件组件的创建和调用 1. Vue 单文件组件的优势 把一个组件全部内容汇合到一个文件中,文件名字是以 .vue ...
- 组件对象模型 COM 的 Python 调用
关于COM的基本概念,可参考组件对象模型 COM 的内容,下面主要介绍两种使用 Python 调用 COM 组件的方法. 1 使用 win32com 1.1 环境搭建 首先需要搭建Python的环境, ...
- 什么是Vue组件?如何创建和使用组件?
啥是组件? 组件就是Vue应用中的小模块,可以重复使用的代码块.组件使得开发大型应用更加容易,因为你可以把代码分成多个小块,每个小块都负责特定的任务,就像搭乐高积木一样. 创建组件 在Vue中创建组件 ...
- C#创建和调用WebService
1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求, ...
- 如何在sqlite3连接中创建并调用自定义函数
#!/user/bin/env python # @Time :2018/6/8 14:44 # @Author :PGIDYSQ #@File :CreateFunTest.py '''如何在sql ...
- MySQL 学习笔记(6)— 存储过程创建、调用、删除以及带参数的存储过程
1. 存储过程总结 存储过程是一种存储在数据库中的程序.它可以包含多个 SQL 语句,并提供许多过程语言的功能,例如变量定义.条件控制语句.循环语句.游标以及异常处理等. 1.1 存储过程优点 实现代 ...
- C#创建和调用DLL
一.写在前面 C# 语言是一种简单但功能强大的编程语言,用于编写企业应用程序. C# 语言从C和 C++语言演化而来,在语句.表达式和运算符方面使用了许多 C++ 功能. C# 语言在类型安全性.版本 ...
- MySQL存储过程的创建及调用
阅读目录:MySQL存储过程_创建-调用-参数 存储过程:SQL中的"脚本" 1.创建存储过程 2.调用存储过程 3.存储过程体 4.语句块标签 存储过程的参数 1.in:向过程里 ...
- Python自定义函数的创建、调用和函数的参数详解
这篇文章主要介绍了Python自定义函数的创建.调用和函数的参数.变量作用域等常见问题,需要的朋友可以参考下 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性 ...
最新文章
- wcf wpf mfc 区别
- linux下tmux
- Linux服务器数据库的导入和导出
- TTU智能配电终端_智能终端+正泰云平台,让配电网更“聪明”
- hdu 1520 Anniversary party(第一道树形dp)
- Java对Map排序
- sqlserver 触发器语法
- 如何查看java安装路径
- NI CompactRIO嵌入式系统开发流程总结
- 如何运用Origin进行曲线拟合
- FreeMarker模板制作
- PostgreSQL 函数
- Intellij IDEA 启动 Spring boot 项目在Run中启动没问题 ,Debug启动缓慢卡住 解决方式
- 计算机资源管理器经常停止运行,win7资源管理器反复停止工作的解决方法[多图]...
- 关于verilog中综合的过程,可综合与不可综合的理解
- 第5节 树形计算亚式期权价格
- 你知道产品经理和项目经理的区别有哪些吗?
- Codeforces Round #702 (Div. 3)——B
- 基于UDP的效劳器端和客户端
- 基于单片机的水壶自动加热系统_基于单片机智能电水壶控制系统设计毕业设计(论文).doc...