IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++】07 新安江模型COM组件 -> 正文阅读

[C++知识库]【C++】07 新安江模型COM组件

1 目标

在完成使用C++以面向对象方式编写三水源新安江模型后,希望进一步把新安江模型做成COM组件的形式(也就是.dll的形式)。

为此,我先跟导师学习了静态库动态库COM的知识,也从网上找到案例复现其创建及调用过程。

现在尝试把新安江模型做成COM组件的步骤记录如下。

2 创建COM组件

  1. 打开Visual Studio 2019 新建ATL项目 → \rightarrow 项目名称:XAJ → \rightarrow 创建 → \rightarrow 勾选支持COM+ 1.0、支持组件注册 → \rightarrow 确定。
    在这里插入图片描述

  2. 添加一个新的ATL对象。右键XAJ项目 → \rightarrow 添加 → \rightarrow 新建项 → \rightarrow ATL → \rightarrow ATL简单对象 → \rightarrow 名称为Model → \rightarrow 添加 → \rightarrow ProgID取名为项目名+“.”+短名称 → \rightarrow 完成。
    在这里插入图片描述
    在这里插入图片描述

  3. 创建自己的方法,即在CModel类中添加调用新安江模型的函数。在头文件Model.h添加函数声明Run(),目的是为了调用原来新安江模型的main()函数。

// Model.h: CModel 的声明

#pragma once
#include "resource.h"       // 主符号



#include "XAJ_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 平台支持的唯一线程模型。"
#endif

using namespace ATL;


// CModel

class ATL_NO_VTABLE CModel :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CModel, &CLSID_Model>,
	public IDispatchImpl<IModel, &IID_IModel, &LIBID_XAJLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
	CModel()
	{
	}

DECLARE_REGISTRY_RESOURCEID(106)


BEGIN_COM_MAP(CModel)
	COM_INTERFACE_ENTRY(IModel)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

public:
	//添加的函数声明
	STDMETHODIMP Run(CHAR* argv[]);


};

OBJECT_ENTRY_AUTO(__uuidof(Model), CModel)
  1. 将三水源新安江模型中的源文件头文件导入到XAJ项目中,并在导入的所有源文件顶部添加#include "pch.h"头文件。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 创建XinanjiangModel.h,输入main()函数声明。
    在这里插入图片描述
//XinanjiangModel.h
#pragma once

//主函数声明
int main(int argc, char* argv[]);
  1. 在源文件Model.cpp添加函数实现,以调用新安江模型main()函数。
// Model.cpp: CModel 的实现


#include "pch.h"
#include "Model.h"

//添加新安江模型的头文件
#include "XinanjiangModel.h"

// CModel

STDMETHODIMP_(HRESULT __stdcall) CModel::Run(CHAR* argv[])
{
	//运行新安江模型
	main(0, argv);

	//默认返回 函数执行正确
	return S_OK;
}

  1. XAJ.idl中添加方法接口设置,如interface IModel : IDispatch中所示,这里的Run()函数为纯虚函数。
// XAJ.idl: XAJ 的 IDL 源
//

// 此文件将由 MIDL 工具处理以
// 生成类型库(XAJ.tlb)和封送处理代码。

import "oaidl.idl";
import "ocidl.idl";

[
	object,
	uuid(a817e7a2-43fa-11d0-9e44-00aa00b6770a),
	dual,
	pointer_default(unique)
]
interface IComponentRegistrar : IDispatch
{
	[id(1)]	HRESULT Attach([in] BSTR bstrPath);
	[id(2)]	HRESULT RegisterAll();
	[id(3)]	HRESULT UnregisterAll();
	[id(4)]	HRESULT GetComponents([out] SAFEARRAY(BSTR)* pbstrCLSIDs, [out] SAFEARRAY(BSTR)* pbstrDescriptions);
	[id(5)]	HRESULT RegisterComponent([in] BSTR bstrCLSID);
	[id(6)] HRESULT UnregisterComponent([in] BSTR bstrCLSID);
};

[
	object,
	uuid(ea7ac902-5dc5-4732-b2dc-46f50fd9385b),
	dual,
	nonextensible,
	pointer_default(unique)
]
interface IModel : IDispatch
{
	//============方法接口设置============//
	[id(1)] HRESULT Run([in] CHAR* argv[1]);
};
[
	uuid(94233707-a67e-4579-9cba-8e92fbf8ee01),
	version(1.0),
	custom(a817e7a1-43fa-11d0-9e44-00aa00b6770a,"{fb867d6b-4a32-4e2f-addd-3047d0103833}")
]
library XAJLib
{
	importlib("stdole2.tlb");
	[
		uuid(fb867d6b-4a32-4e2f-addd-3047d0103833)
	]
	coclass CompReg
	{
		[default] interface IComponentRegistrar;
	};
	[
		uuid(e002b0ec-9a5c-44c8-8b96-bb7648d05f25)
	]
	coclass Model
	{
		[default] interface IModel;
	};
};

import "shobjidl.idl";

  1. 解决方案配置选择Release,平台选择x64,右键XAJ项目生成。XAJ.dll 为 64位的COM 组件。XAJ.dllXAJ.tlb 是之后 C++ 调用COM所需要引入的文件。
    在这里插入图片描述

3 注册COM组件

  1. 注意: 根据COM组件位数选择regsvr32.exe,如果COM组件为32位,用C:\Windows\System32\regsvr32.exe注册;如果COM组件为64位,则用C:\Windows\SysWOW64\regsvr32.exe注册。

因为上一步选择x64,所以这里的COM组件是64位的,所以应该用C:\Windows\SysWOW64\regsvr32.exe注册。

  1. 注册。以管理员身份打开powershell,依次输入如下代码,完成注册。
cd E:\Research\XinanjiangModel\Myself\COM\XAJ\x64\Release
C:\Windows\SysWOW64\regsvr32.exe -i  XAJ.dll

在这里插入图片描述

  1. 或者以管理员身份打开CMD,依次输入如下代码,完成注册。
E:
cd E:\Research\XinanjiangModel\Myself\COM\XAJ\x64\Release
C:\Windows\SysWOW64\regsvr32.exe -i  XAJ.dll

在这里插入图片描述

4 调用COM组件

  1. 打开Visual Studio 2019,文件 → \rightarrow 新建 → \rightarrow 项目 → \rightarrow 控制台应用 → \rightarrow 创建XAJCOMAPP项目。
    在这里插入图片描述
  2. 在源文件XAJCOMAPP.cpp中引入动态库文件XAJ.dll目录。解决方案配置选择Debug → \rightarrow 平台选择x64 → \rightarrow 右键XAJCOMAPP项目 → \rightarrow 配置属性 → \rightarrow C/C++ → \rightarrow 常规 → \rightarrow 附加包含目录 → \rightarrow 新行 → \rightarrow 选择动态库目录。这里的平台位数必须与COM组件位数一致。
    在这里插入图片描述
  3. XAJCOMAPP.cpp中输入如下代码:
// XAJCOMAPP.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

#import "XAJ.dll"	 raw_interfaces_only raw_native_types no_namespace named_guids

int main(int argc, char* argv[])
{
	//初始化 COM 库,用来告诉 Windows 以单线程的方式创建 COM 对象
	::CoInitialize(0);

	//指向ITEMP类的智能指针
	IModelPtr pModel = nullptr;
	//创建 COM 组件对象,有两种方式
	//HRESULT hr = pModel.CreateInstance(CLSID_Model);     //使用CLSID创建
	HRESULT hr = pModel.CreateInstance("XAJ.Model");       //使用ProgID创建

	//调用新安江模型
	pModel->Run(argv);

	return 0;
}
  1. 点击本地Windows调试器,成功调用新安江模型COM组件。在x64\Debug\文件夹内生成流域出口流量过程Q.txt,但由于该路径下没有新安江模型的输入文件,所以Q.txt为空文件,文件大小为0KB。
    在这里插入图片描述
  2. 在该路径下创建如下图5个新安江模型输入文件,再点击本地Windows调试器或XAJCOMAPP.exe,即可生成流域出口流量过程Q.txt
    在这里插入图片描述
    在这里插入图片描述

5 参考资料

“类未注册(HRESULT异常:0x80040154(REGDB_E_CLASSNOTREG))”

6 本机目录

创建和注册COM组件目录:E:\Research\XinanjiangModel\Myself\COM\XAJ\x64\Release
调用COM组件目录:E:\Master\study\Cpp\XAJCOMAPP\x64\Debug

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 11:33:49  更:2021-08-16 11:34:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 15:46:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计