大家都来谈谈COM,从COM源码的编写、注册、调用、远程调用等等想到哪说呢!UP有分!!1 当然这个说起来几天也说不完,现在我在看<<COM+技术大全>>不过现在我对它的编写、调用、远程调用的过程搞不太清楚,细节可以慢慢看书,但它的整个过程现在有些糊涂,大家帮我讲一讲。最好有一个简单的例子,哈! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 1:服务器端 在MFC工程中加入ATL支持,加入接口和方法,生成projectname_i.h projectname_i.c projectname_p.c dlldata.h文件。 projectname_i:对接口的c++定义 projectname_h:对接口的CLSID和IID定义 dlldata:生成代理文件需要dlldata.obj 然后编译代理文件, 语法 nmake -f projectnamePS.mk 需要dlldata.obj,projectname_i.obj,projectname_p.obj2:客户端 #include "mfcserver_i.h" //对接口IAdd的描述 void CMFCClientDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 const IID IID_IAdd = {0x3F153D2D,0xF707,0x429B,0x97,0x69,0xED,0xD5,0xAE,0xF0,0x82,0x1E};//interface Id const CLSID CLSID_Add ={0xE8B5BD5A,0xC013,0x44FA,0x99,0x8F,0x59,0xA5,0x00,0x4E,0xEC,0x77};//com class id BSTR bstrHostName; CString str; str.Format("%s","192.168.0.2"); bstrHostName=str.AllocSysString();//为bstr类型分配内存 COSERVERINFO si;//设置服务器信息 si.dwReserved1=si.dwReserved2=0; si.pwszName=bstrHostName; si.pAuthInfo=NULL; MULTI_QI mqi[1]; mqi[0].pIID=&IID_IAdd; mqi[0].pItf=NULL; mqi[0].hr=0; IAdd *g=NULL; CoInitialize(NULL);//初始化com资源,必须的 HRESULT hr; hr=CoCreateInstanceEx( CLSID_Add, NULL, CLSCTX_REMOTE_SERVER, &si, 1, mqi ); if(hr!=S_OK) MessageBox("create error!"); else { g=(IAdd *)mqi->pItf; CoCreateInstance(CLSID_show,NULL,CLSCTX_LOCAL_SERVER,IID_Ishow,(void **)&p); g->addvice(p);//传入回调函数 g->Add(8700,100); g->AddRef(); } CoUninitialize();//释放com资源}3:代理 nmake -f projectnamePS.mk生成.dll文件 用projectnamePS.dll注册 4:注册 EXE服务器注册: exefilename.exe /regserver exefilename.exe /unregserver DLL代理注册: regsvr32 dllfilename.dll注意事项: VC7.0的MFC生成的.mk文件需要复制以下代码覆盖以前的: .c.obj: cl /c /Ox /DWIN32 /D_WIN32_WINNT=0x0400 /DREGISTER_PROXY_DLL \ $< 回调接口应将对接口的定义文件包含到IDL文件中,不然会遇到接口类型未知的错误。 可以在项目属性的[自定义生成步骤]中加入nmake -f projectnamePS.dll 输出为projectnamePS.dll 执行 编译 ATL远程服务器的注册: 1。运行com viewer改变对象的属性:把inproc server设为代理projectnamePS.dll 2。把代理进程改为 EXE服务器对应的位置 3。最后一步:运行dcomcnfg配置 a.运行DCOM服务器 b.默认身份验证级别改为 无建议: 编写服务器部分应使用ATL编写,MFC嵌入ATL编程存在无法DCOM配置的问题 若要在DCOM中传递自定义类型的数据请使用IUnknown接口为基类. 1.建立服务器,定义接口类型为Apartment,Custom,yes,并添加方法,其中可使用 在IDL文件中定义的数据类型。定义形式: typedef struct { int l; char df[200]; }MYSTRUCT;2.建立客户端,复制IID,CLSID定义文件,并包含接口定义文件.c 这时使用OLE/COM viewer将该接口对象设置为LOCAL型,实现本地调用ocreateInstance(..LOCAL_SERVER..), 这时候还不能实现COM的远程调用,因为还没有注册代理/存根文件。3.编译代理文件,nmake -f ps.mk生成大约24k的ps.dll文件,然后用regsvr32 ps.dll注册它。 目前为止,已经可以运行客户程序,但是会出现乱字符等问题,代理没有正常运行,问题出在代理上,需要将返回的参数用[out]标记,这样汇集器便能正常工作了。4.对注册表的修改,最好使用DCOMCNFG和OLE/COM viewer配置 (1)将接口对象的进程内服务器设为代理DLL文件 (2)将代理进程设为server.EXE文件,本地服务器可以不设 (3)修改DCOMCNFG,将DCOM设为[开启],默认身份验证为[无],模拟级别为匿名 请教 insert into 的问题 又是关于ActiveX控件下载的问题,希望大家都来讨论一下!!!! 两个类怎么互相调用 Dialog的问题! 请大家帮助我解决这样一个windows服务的问题? 在读取管道的时候可以进行超时控制吗? 如何从jpg和bmp文件得到它的以bmp文件格式保存的缩略图? 线程消息 如果我在一个表中有个字段是可以自动增量的,那么..... 在做rev()时,是否会同时接到多条数据,怎么处理?谢谢! 从不拖欠!来者有分,解决问题另开200分, 100分 讨论一下怎样在一个对话上创建一个自己派生的窗口~方法越多越好!来吧,在线给分
projectname_h:对接口的CLSID和IID定义
dlldata:生成代理文件需要dlldata.obj
然后编译代理文件,
语法 nmake -f projectnamePS.mk 需要dlldata.obj,projectname_i.obj,projectname_p.obj
2:客户端
#include "mfcserver_i.h" //对接口IAdd的描述
void CMFCClientDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
const IID IID_IAdd = {0x3F153D2D,0xF707,0x429B,0x97,0x69,0xED,0xD5,0xAE,0xF0,0x82,0x1E};//interface Id
const CLSID CLSID_Add ={0xE8B5BD5A,0xC013,0x44FA,0x99,0x8F,0x59,0xA5,0x00,0x4E,0xEC,0x77};//com class id
BSTR bstrHostName;
CString str;
str.Format("%s","192.168.0.2");
bstrHostName=str.AllocSysString();//为bstr类型分配内存
COSERVERINFO si;//设置服务器信息
si.dwReserved1=si.dwReserved2=0;
si.pwszName=bstrHostName;
si.pAuthInfo=NULL;
MULTI_QI mqi[1];
mqi[0].pIID=&IID_IAdd;
mqi[0].pItf=NULL;
mqi[0].hr=0;
IAdd *g=NULL;
CoInitialize(NULL);//初始化com资源,必须的 HRESULT hr;
hr=CoCreateInstanceEx(
CLSID_Add,
NULL,
CLSCTX_REMOTE_SERVER,
&si,
1,
mqi
);
if(hr!=S_OK)
MessageBox("create error!");
else
{
g=(IAdd *)mqi->pItf;
CoCreateInstance(CLSID_show,NULL,CLSCTX_LOCAL_SERVER,IID_Ishow,(void **)&p);
g->addvice(p);//传入回调函数
g->Add(8700,100);
g->AddRef();
}
CoUninitialize();//释放com资源
}
3:代理
nmake -f projectnamePS.mk生成.dll文件
用projectnamePS.dll注册
4:注册
EXE服务器注册:
exefilename.exe /regserver
exefilename.exe /unregserver
DLL代理注册:
regsvr32 dllfilename.dll
注意事项:
VC7.0的MFC生成的.mk文件需要复制以下代码覆盖以前的:
.c.obj:
cl /c /Ox /DWIN32 /D_WIN32_WINNT=0x0400 /DREGISTER_PROXY_DLL \
$<
回调接口应将对接口的定义文件包含到IDL文件中,不然会遇到接口类型未知的错误。 可以在项目属性的[自定义生成步骤]中加入nmake -f projectnamePS.dll 输出为projectnamePS.dll 执行 编译
ATL远程服务器的注册:
1。运行com viewer改变对象的属性:把inproc server设为代理projectnamePS.dll
2。把代理进程改为 EXE服务器对应的位置
3。最后一步:运行dcomcnfg配置
a.运行DCOM服务器
b.默认身份验证级别改为 无
建议:
编写服务器部分应使用ATL编写,MFC嵌入ATL编程存在无法DCOM配置的问题
typedef struct
{
int l;
char df[200];
}MYSTRUCT;
2.建立客户端,复制IID,CLSID定义文件,并包含接口定义文件.c
这时使用OLE/COM viewer将该接口对象设置为LOCAL型,实现本地调用ocreateInstance(..LOCAL_SERVER..), 这时候还不能实现COM的远程调用,因为还没有注册代理/存根文件。3.编译代理文件,nmake -f ps.mk生成大约24k的ps.dll文件,然后用regsvr32 ps.dll注册它。
目前为止,已经可以运行客户程序,但是会出现乱字符等问题,代理没有正常运行,问题出在代理上,需要将返回的参数用[out]标记,这样汇集器便能正常工作了。
4.对注册表的修改,最好使用DCOMCNFG和OLE/COM viewer配置
(1)将接口对象的进程内服务器设为代理DLL文件
(2)将代理进程设为server.EXE文件,本地服务器可以不设
(3)修改DCOMCNFG,将DCOM设为[开启],默认身份验证为[无],模拟级别为匿名