参考:

- 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的创建和调用相关推荐

  1. 使用vue-cli创建Vue工程化项目及单文件组件的创建和调用

    文章目录 1. Vue 单文件组件的优势 2. cli 创建 Vue 工程项目 3. 单文件组件的创建和调用 1. Vue 单文件组件的优势 把一个组件全部内容汇合到一个文件中,文件名字是以 .vue ...

  2. 组件对象模型 COM 的 Python 调用

    关于COM的基本概念,可参考组件对象模型 COM 的内容,下面主要介绍两种使用 Python 调用 COM 组件的方法. 1 使用 win32com 1.1 环境搭建 首先需要搭建Python的环境, ...

  3. 什么是Vue组件?如何创建和使用组件?

    啥是组件? 组件就是Vue应用中的小模块,可以重复使用的代码块.组件使得开发大型应用更加容易,因为你可以把代码分成多个小块,每个小块都负责特定的任务,就像搭乐高积木一样. 创建组件 在Vue中创建组件 ...

  4. C#创建和调用WebService

    1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求, ...

  5. 如何在sqlite3连接中创建并调用自定义函数

    #!/user/bin/env python # @Time :2018/6/8 14:44 # @Author :PGIDYSQ #@File :CreateFunTest.py '''如何在sql ...

  6. MySQL 学习笔记(6)— 存储过程创建、调用、删除以及带参数的存储过程

    1. 存储过程总结 存储过程是一种存储在数据库中的程序.它可以包含多个 SQL 语句,并提供许多过程语言的功能,例如变量定义.条件控制语句.循环语句.游标以及异常处理等. 1.1 存储过程优点 实现代 ...

  7. C#创建和调用DLL

    一.写在前面 C# 语言是一种简单但功能强大的编程语言,用于编写企业应用程序. C# 语言从C和 C++语言演化而来,在语句.表达式和运算符方面使用了许多 C++ 功能. C# 语言在类型安全性.版本 ...

  8. MySQL存储过程的创建及调用

    阅读目录:MySQL存储过程_创建-调用-参数 存储过程:SQL中的"脚本" 1.创建存储过程 2.调用存储过程 3.存储过程体 4.语句块标签 存储过程的参数 1.in:向过程里 ...

  9. Python自定义函数的创建、调用和函数的参数详解

    这篇文章主要介绍了Python自定义函数的创建.调用和函数的参数.变量作用域等常见问题,需要的朋友可以参考下 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性 ...

最新文章

  1. wcf wpf mfc 区别
  2. linux下tmux
  3. Linux服务器数据库的导入和导出
  4. TTU智能配电终端_智能终端+正泰云平台,让配电网更“聪明”
  5. hdu 1520 Anniversary party(第一道树形dp)
  6. Java对Map排序
  7. sqlserver 触发器语法
  8. 如何查看java安装路径
  9. NI CompactRIO嵌入式系统开发流程总结
  10. 如何运用Origin进行曲线拟合
  11. FreeMarker模板制作
  12. PostgreSQL 函数
  13. Intellij IDEA 启动 Spring boot 项目在Run中启动没问题 ,Debug启动缓慢卡住 解决方式
  14. 计算机资源管理器经常停止运行,win7资源管理器反复停止工作的解决方法[多图]...
  15. 关于verilog中综合的过程,可综合与不可综合的理解
  16. 第5节 树形计算亚式期权价格
  17. 你知道产品经理和项目经理的区别有哪些吗?
  18. Codeforces Round #702 (Div. 3)——B
  19. 基于UDP的效劳器端和客户端
  20. 基于单片机的水壶自动加热系统_基于单片机智能电水壶控制系统设计毕业设计(论文).doc...

热门文章

  1. 专精特新企业认定条件 这些条件要满足
  2. 《深入理解 Java 虚拟机》转载周志明
  3. 信号调理方式(放大、滤波、隔离、调制解调等)
  4. 切勿忽视晶振的选型设计!
  5. java考勤系统数据库_java考勤管理系统数据库实现
  6. Ruby 函数式编程
  7. ECC的“点加”和“点乘”
  8. Application context和Activity context的区别
  9. 【转载】解决illustrator cs6提示错误16的方法
  10. AppScan 扫描web应用程序