C++中COM组件的创建和调用

前几天项目中用到COM组件,趁此写个demo记录一下在C++中COM组件的创建和调用(PS:demo开发使用VS2010)。

一,创建COM组件

1.打开VS2010,新建项目,选择ATL项目,工程命名为TempCom。
选择ATL项目
一路下一步,完成项目的创建。可以看到自动创建了两个工程,“TempCom”和“TempComPS”
2.在“TempCom”工程名上右键,选择“添加”->“类”,在打开的
添加类对话框中选择“ATL简单对象”
在这里插入图片描述
点击“添加”后打开“ATL简单对象向导”对话框,在这里添加要导出的接口名或者说类名,比如我添加一个“TmpAdd”临时加法的接口,和一个“TmpMult”临时乘法的接口。
在这里插入图片描述
这时可以看到工程中自动产生了“TmpAdd”的.h头文件和.cpp源文件,其他的一路下一步,按照上面方式再添加“TmpMult”临时乘法的接口在此不作赘述;
3.给接口类添加方法
在工程的类视图模式中,可以看到刚刚添加的两个接口“ITmpAdd”,“ITmpMult”,注意:工程在你输入的名称前自动添加“I”和“C”分别表示对应的接口名和类名,后续导入到测试工程的时候可以看到
在这里插入图片描述
在上面“ITmpAdd”右键,选择“添加”->“添加方法”,打开添加方法向导,输入方法和参数,这里我给“ITmpAdd”添加整型加法IntAdd的方法,两个LONG型的入参“add1”和“add2”,一个LONG*型的出参“ret”;
在这里插入图片描述
以此方式,再给“ITmpAdd”接口添加一个表示浮点型加法的“FloatAdd”方法;给“ITmpMult”接口分别添加计算整数乘法和浮点数乘法的“IntMult”方法和“FloatMult”方法;
4.实现上面添加的方法
打开“TmpAdd.cpp”文件,可以看到前面添加方法自动产生的方法代码,实现“IntAdd”和“FloatAdd”,同理实现“TmpMult.cpp”文件中的“IntMult”和“FloatMult”方法。
在这里插入图片描述
5.编译
代码完成后,就可以编译输出,在此我编译时报错:未能注册输出。。。
在这里插入图片描述
可以通过打开工程“属性”->“链接”->“常规”->“逐用户重定向”的“否”改为“是”,解决这个问题
在这里插入图片描述
再次重新编译成功,生成了“TempCom.dll”。
6.注册
此时,你的COM组件的DLL就可以输出给别人使用了。一般别人拿到会统一打包在一个安装包里,安装包会实现COM组件注册,这里我们只是demo测试,我就自己手动注册:将生成的release版本的“TempCom.dll”放在系统目录“C:\Windows\SysWOW64”,我生成的是32位的,为了方便注册,就直接放这里,在系统目录“C:\Windows\SysWOW64”下,以管理员身份打开"cmd.exe",输入:regsvr32 TempCom.dll,回车,完成注册。
控件的注册

二。COM组件的调用

1.注册COM组件,被人给来的COM组件,你要调用,首先要确保注册成功,前文已经讲了注册方法,再次不做赘述;
2.创建测试工程
打开VS2010,新建项目,选择“MFC应用程序”,工程命名为TempComTest。搞个对话框来测试前面的COM组件;
在这里插入图片描述
弄几个编辑框和按钮,搞个简单的加法和乘法的算式样子
在这里插入图片描述
3.导入COM组件
在代码中添加一下代码,便导入你要调用的COM组件
在这里插入图片描述
编译,发现生成目录下,产生了“tempcom.tlh”和“tempcom.tli”文件,说明导入COM成功,可以打开“tempcom.tlh”文件看下,有你定义的接口名称和对应的UUID;
4.调用COM组件的方法;
COM组件的调用方式有很多种,在此举例两种:
A例:使用#import纯代码形式导入实现

void CTempComTestDlg::OnBnClickedButtonAdd()
{
	// TODO: 在此添加控件通知处理程序代码
	CString cstrAdd1 = _T("");
	CString cstrAdd2 = _T("");
	CString cstrRet = _T("");
	m_edtAdd1.GetWindowText(cstrAdd1);
	long lAdd1 = _ttoi(cstrAdd1);
	m_edtAdd2.GetWindowText(cstrAdd2);
	long lAdd2 = _ttoi(cstrAdd2);

	CoInitialize(NULL);  
	CLSID clsid;  
	CLSIDFromProgID(OLESTR("TempCom.TmpAdd"),&clsid); //"TempCom.TmpAdd"即为Dll名+Com对象名  
	{  
		CComPtr<ITmpAdd> pMyAdd;  
		pMyAdd.CoCreateInstance(clsid);  
		long ret;  
		ret = pMyAdd->IntAdd(lAdd1,lAdd2);  
		//ret = pMyAdd->FloatAdd(lAdd1,lAdd2); 
		cstrRet.Format(_T("%d"),ret);
		m_edtRet1.SetWindowTextW(cstrRet);
	}  
	CoUninitialize();  
	return ;  
}

B例,使用MFC Class Wizard协助导入加代码实现(推荐,这样可以看到该COM内部所有接口类,对于一些内部众多接口类的复杂COM控件比较清楚)
在测试工程“TempComTest”上右键,选择“类向导”,打开的MFC类向导中选择“添加类”->“类型库中的MFC类”,打开类型库向导如下图,可以通过选择注册表,在可用的类型库中找到你的COM组件名,或者通过选择文件,在位置蓝选择你的COM组件位置,选中后,下方接口就出现了你COM组件中的所有接口名,你可以只选择自己用的几个进行添加,添加后,自动在你的测试工程中产生了接口类对应的类的头文件如demo中COm组件的“CTmpAdd.cpp”和"CTmpMult",后面就比较简单,我们基本像调用普通类一样调用类里边的方法。
在这里插入图片描述

	CoInitialize(NULL);
	CTmpMult getMult;	//创建接口类的对象
	//"TempCom.TmpMult"是接口类的ProgID,也可以使用.tlh文件中的uuid
	if (getMult.CreateDispatch("TempCom.TmpMult") != 0)	
	{
	//调用
		ret = getMult.IntMult(25, 4);
		getMult.ReleaseDispatch();
	}
	CoUninitialize();

至此,COM组件在C++中的创建和调用已全部实现

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用C++调用COM组件需要遵循以下步骤: 1. 在Visual Studio创建一个Windows控制台应用程序项目。 2. 在项目添加一个头文件,该头文件包含COM组件的接口定义。 3. 在代码使用CoCreateInstance函数创建COM组件的实例。 4. 调用COM组件的方法。 下面是一个简单的示例,展示如何使用C++调用COM组件的方法: ```cpp #include <windows.h> #include <tchar.h> #include <iostream> #include <comdef.h> // 定义COM组件的接口 struct IMyComponent : public IUnknown { virtual HRESULT __stdcall MyMethod() = 0; }; int main() { // 初始化COM库 CoInitialize(NULL); // 创建COM组件的实例 IMyComponent* pMyComponent = NULL; HRESULT hr = CoCreateInstance( CLSID_MyComponent, // COM组件的CLSID NULL, CLSCTX_INPROC_SERVER, // COM组件的类型 IID_IMyComponent, // COM组件的接口ID reinterpret_cast<void**>(&pMyComponent)); if (FAILED(hr)) { std::cout << "Failed to create instance of COM component." << std::endl; return 1; } // 调用COM组件的方法 hr = pMyComponent->MyMethod(); if (FAILED(hr)) { std::wcout << _com_error(hr).ErrorMessage() << std::endl; return 1; } // 释放COM组件的实例 pMyComponent->Release(); // 终止COM库 CoUninitialize(); return 0; } ``` 在上面的示例,我们首先使用CoCreateInstance函数创建COM组件的实例,然后调用COM组件的MyMethod方法。 需要注意的是,如果COM组件是以Out-of-Process的方式运行的,我们需要使用CLSCTX_LOCAL_SERVER参数来创建COM组件的实例。另外,如果COM组件不是以STA(Single-Threaded Apartment)方式运行的,我们需要在调用CoInitialize之前设置线程模型为STA。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值