up

解决方案 »

  1.   

    http://www.vckbase.com/document/viewdoc.asp?id=213
    http://www.vckbase.com/document/viewdoc.asp?id=212
      

  2.   

    看完http://www.5xsoft.com/data/200107/2520030001_1.htm
    保你会COM编程,不过COM是一种思想,最重要的是理解COM思想
      

  3.   

    msdn是最好的书!microsoft 太强了
      

  4.   

    ATl应用: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.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配置的问题 
      

  5.   

    若要在DCOM中传递自定义类型的数据请使用IUnknown接口为基类.
    使用IDispatch接口,在传递过程中会出错。!!
    客户端代码:
    CoUninitialize();
    CoUninitialize();
    //将IP地址转换为BSTR 类型
    BSTR bstrHostName;
    CString m_IP;
    m_IP.Format("%s","192.168.0.2");
    bstrHostName=m_IP.AllocSysString();
    //初始化服务器信息
    COSERVERINFO si;
    si.dwReserved1=si.dwReserved2=0;
    si.pwszName=bstrHostName;
        si.pAuthInfo=NULL;
    //要获得的接口指针
    MULTI_QI mqi[1];
    mqi[0].pIID=&IID_IDual_str;
    mqi[0].pItf=NULL;
    mqi[0].hr=0;
    //定义iGame接口
        IDual_str *game=NULL;
    GetDlgItem(IDC_SERVERSTATE)->SetWindowText("正在连接...");
    HRESULT hr=CoCreateInstanceEx(CLSID_Dual_str,NULL,CLSCTX_REMOTE_SERVER,&si,1,mqi);
    //处理返回
    if(hr!=S_OK)
    {
    GetDlgItem(IDC_SERVERSTATE)->SetWindowText("连接失败");
    }
    else
    {
    game=(IDual_str *)mqi->pItf;
    if(game==NULL){GetDlgItem(IDC_SERVERSTATE)->SetWindowText("无法连接");return;}
    STR g;
    game->getstr(&g);
    MessageBox((char *)g.str);
      game->Release();//释放COM对象
    }
      

  6.   

    COM_使用Custom接口实现DCOM1.建立服务器,定义接口类型为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设为[开启],默认身份验证为[无],模拟级别为匿名5.现在可以使用分布通信了,客户只要安装 代理和GUI 就可以了6.要在定制接口中使用字符串,必须在IDL文件中使用[string][in]
      

  7.   

    to Greaitm
    你用的是什么向导?
    dll?
    atl?
    mfc?
      

  8.   

    上午时,很高兴,写了一些 有了dll 干嘛还要 com dll的问题,
    对于理解com,编写com 可能会有帮助:
    (转自:http://expert.csdn.net/Expert/topic/1334/1334607.xml?temp=.6936304)回复人: fanchka(狼仔) ( ) 信誉:100  2003-01-08 11:36:00  得分:0   to:HardWorking () 其实,这个问题就是对com的疑惑. 换句话说,既然有了dll,干吗还要com形式的dll?那偶就做个导游,说一些. 
    dll在传统的程序员眼里,就是一个建个win32 dll工程,写个dllmain(),写个
    导出函数,一编译,就ok拉.  一个dll,是不是很简单? 确实,exe调用dll也是
    很简单,它(dll)更象一个函数体,来供exe调用.当然,它们处在同一个进程内.好,下面就提问题了:我能不能写个第二版本的dll,来直接替换? 如果我导出的
    是一个类的构造函数,和它的一个成员函数,并且再二版中,我又给它(类)加了
    一个私有变量,这样直接替换行不行?先说问题1: 最终结果很难说. 你替换之后,可能会正常工作,可能会出现莫名其妙
    的返回值,可能会死掉进程,可能会死机,可能会格式化硬盘...不可测. 你会问
    为什么? 看第二个问题.问题2:   在版本1,我导出一个构造函数,和它的一个成员函数,在exe中,按常规
    方式我把编译dll时的.h 和 .lib嵌入进来,编译好,运行正常. 好进行2版的
    替换,我直接把dll复制过来,替换原先的dll. 假设,在exe中你是这样写的代码: 
    int main() {
    CMydll mydll;
    for(int i=0;i<10000;++i)
        itest = mydll.MenberFunc();
      ... ...
    }那么,for会进入死循环.(我测试过) 你会问 why??   i的 内存被重复i和
    新添的哪个私有变量轮换霸占,它俩都在不断的写入自己的值. 死循环.你有会问,为什么? 记得你嵌入的.h 和.lib吗? exe在编译时期会根据这些
    信息"决定CMydll对象的大小"! 记得咱们在 2版时加入的私有变量吧?
    那么"CMydll对象的大小"变大了吧? 可是exe不知道啊,它很笨,还是按原先
    的方式分内存的.... 悲剧如上上映. 你会问我,花了这么多口水,一个com没提,不是废话吗?  com要解决的一个重
    大问题,就是二进制的可替换性!!  那你又会问,上面这种问题如何解决?
    呵呵,com来了,姗姗来迟的这种. 接口!! 什么是接口? (用c++说) 抽象基类.
    里面全部是纯虚拟函数,没有任何成员变量. 有问,为什么要这样? c++编译器
    厂商大战的结局. 那群乌鸦对类的内存分布,各持己见 (主指vtbl). 而有的
    乌鸦,把成员变量放在内存虚拟表的首位,有的在末位...所以com不许有成员变量.如此以来,不仅解决了替换问题,还为跨语言,跨平台提供了基础. 继续.
    为了在 真正意义上实现重用性,需要有种标准,不能a公司的代码,那到b公司
    就不能用了,就出现了统一接口: IUnknown. 为了exe不管dll具体在什么位置
    而能够调用,就采用了windows的注册表,和GUID.  为了实现跨编程语言,而
    定义IDispatch. 为了实现远程调用,而用RPC和代理/存根.呼... 看看,Com的dll 和常见的dll,还有什么不同?
    哦,com+ 和com的不同是: 通常的com对系统明显的依赖是注册表.
    com+可多的多了. 它在com的基础上,进一步发展,为的是解决 同步,事务...
    这些都要依靠win2k的鼎立支持: mts msmq... 诺,你看到了,尽是服务
    (系统给的). 当然,com+为了能够利用这些服务,只有一个IUnknown和
    IDispatch是不够的,它又开发了许多系统接口,象OC(组件对象环境)所拥有
    的个个固定接口,咱们可以访问,当然.