如题,公司任务,本人做.net的,对ATL不了解,试了两天,没搞明白,所以来请教诸位大侠了。
初始条件如下:
1. 项目是一个大型软件的子功能插件。
2. 项目需要使用主软件提供的公共接口,即idl文件。
3. 主软件提供的公共目录中包含如下文件:X.idl X.tli X.tlb X.tlh X.h X_i.c X_p.c dlldata.c 
我做了什么:
1. 我新建了一个ATL项目,在项目中添加了(add)X.idl文件,编译通过
2. 为项目添加一个ATL Simple Object类 TrainingX,编译通过
3. 对TrainingX执行Add->Implement Interface... ,实现X.idl 中接口:IXHello, 编译出错,提示信息如下:
Error 1 error LNK2001: unresolved external symbol _LIBID_XLib TrainingX.obj 项目
Error 2 fatal error LNK1120: 1 unresolved externals e:\项目\Debug\项目.dll 1 项目找不到原因,我哪做错了??明码标价,童叟无欺:提供帮助者60分,打酱油20分,如果自己解决权当散分,3天不解决也散分。各位大侠多多关照,小弟这里提前谢过。

解决方案 »

  1.   

    X.idl X.tli X.tlb X.tlh X.h X_i.c X_p.c dlldata.c 
    这些文件只是一些接口信息和编译连接后的文件,对实际操作没什么意义
      

  2.   

    http://blog.csdn.net/akirya/archive/2008/02/17/2100501.aspx
    参考C调用部分即可。
      

  3.   

     我想是我没说清楚:
    1. 回复akirya:我要实现的部分是被调用者,有就是Server,而我说的主软件才是调用者。
    换句话说,就是我要用外来的Idl实现一个server。不知道这次说清楚了没。
    2. 回复ouyh12345:第1我并非没有搜过,第2我也不是对COM一点都不懂,所以您的回复对我一点帮助都没有。不好意思。
      

  4.   

    我这有理解对不对:现在需要你开发一个ATL,大型软件需要调用这个ATL里面提供的接口?
      

  5.   

    to:wangchaoyu2001 是这样的
    to: akirya 我不调用它,它调用我,但我要实现它提供的统一接口,因为还有别的插件。具体过程是,先注册我的插件,然后主软件检索发现我的存在,然后调用我。就这样。诸位辛苦啊!我郁闷,感觉是个超级简单的问题,可我就是搞不出来。有人说,既然有了tlh 和tli直接引进来就可以了,不用再管idl了。我试了下,不行,不明白啊,难道是我那里搞错了。
      

  6.   

    2. 项目需要使用主软件提供的公共接口,即idl文件。 这个怎么解释,你的工程不需要调用主软件的任何方法?
      

  7.   

    回复:akirya 或者我换一种说法,主软件需要调用一种组件,这种组件可以有很多个,但它们都实现了相同的接口也就是说,主软件其实才是客户端,这样是不是明白些了
      

  8.   

    2. 项目需要使用主软件提供的公共接口,即idl文件。
    idl是ATL工程中的一个文件,里面有ATL提供的接口的声明.
    这样就有2种理解:
    a. 你开发的ATL还要调用住软件提供的接口
    b. 你要按照主软件提供的idl文件中声明的接口格式来开发哪一个理解正确?
      

  9.   

    To wangchaoyu2001: 我选B
      

  10.   

    那就可以创建ATL工程了,按照idl文件里的格式add method
      

  11.   

    to 12楼: 
    你的意思是说:我只要根据原来IDL文件中的格式来声明接口、成员,并不需要理会原IDL中的"uuid(CAF0E75E-5EF6-4709-A4CD-A44D1A034C42)"这种东西吗?好像不行吧?
      

  12.   

    既然你开发的ATL不需要调用其他的接口,那原idl中的uuid也没啥用了.我给你发消息了,你要是方便就加qq,在帖子上回复效率太低.
      

  13.   

    我换一种提法,场景是这样的:
        现有系统是一个Client 和多个 server构成的系统,client 调用 server提供的一组COM接口实现某些功能。但由于业务变更,原来的server已经不能满足需求,此时需要更换server。但由于并没有server的源码,必须重新开发。为了不影响client的工作,新server必须与原server接口相同;所幸,我们找到了原server开发时使用的X.idl和其编译生成的文件。这样必须以原来的*.idl 为基础开发。    于是问题来了。我试图将这个原有的idl引入一个新建的project中,但无论我如何尝试,都无法成功,请问:如果将一个已存在的idl应用于新项目中呢?
      

  14.   

    to: wangchaoyu2001
    555 我只要msn
      

  15.   

    我明白你的意思,就是要重新开发一个ATL替换原有的,所有接口都不变.
    那么新的工程中,是否已按照原有idl中声明的格式实现了所有接口?
    函数名,参数个数,参数类型,返回值都一致.
      

  16.   

    还没, 我只是将原来的idl作为文件添加,然后添加对象,再继承原idl中的接口。编译就不能过了。你的意思是我只要按照原来的样子做就可以了吗
      

  17.   

    这样恐怕不行.你按照下面的做法:
    对于你的情况,只要保证新旧两个ATL的接口和uuid完全一致即可.
    1. 新建一个ATL工程,在类视图中添加ATL组件类,然后添加方法
    2. 添加方法时确保与原有idl中的接口格式完全一致
    3. 修改新工程的uuid,包括新工程的idl和rgs两个文件,把对应的uuid都改成旧的,重新编译并注册即可
      

  18.   

    更正:"1. 新建一个ATL工程,在类视图中添加ATL组件类,然后添加方法"
    应为:在类视图中添加ATL对象
      

  19.   

    我用的是VC6,2003/2005或更高版本创建ATL工程和添加方法的操作应该不一样.
      

  20.   

    To:wangchaoyu2001
    听起来可行,thank you 这个方法我先试试。没有更正规的做法吗?难道微软没有考虑到这种情况?还有没有别的方法,比如直接引用.tlh之类的,同事说可以,问他又说不明白,只说以前的几个插件也是这么做的。
      

  21.   

    我问了同事,那个方法以前用过,可行.
    直接引用.tlh这个我不懂,呵呵.
      

  22.   

    周一结贴,只要可行,wangchaoyu2001独得40,留20分给提供其他方法的人。akirya的博客不错5分,ouyh12345第一个回复3分,还剩下12分预计平分给其他捧场的。分数不值一提,关键是学到东西,给分是因为我无以为报,散分是为了图个热闹。小弟在此谢先过各位热情回复。
      

  23.   


    看到这我心都凉了
    还是说两句吧
    如果你拿到了旧的idl了,先不要急着去修改它的idl,自己新建一个ATL工程,增加好你的对象,接口,然后把你的idl拷到旧的idl下面,建立一个idl project,然后把两个idl加进来。设置下工程属性中的MIDL选项的路径,如果把旧idl作为你的主idl,那么把你的idl设置为“从生成中排除”,旧idl里面需要把你idl的接口声明写进来:[
    uuid(2FB6BDAC-088C-4A5F-BC00-CD84B6E1F90B), 
    version(1.0), 
    helpstring("GeoPower Commponet 1.0")
    ]library OldIDL
    {
        import "my.idl";//你的idl
        [
    uuid(899474A0-43F9-4f9c-A496-26432E15AFFD), 
    version(1.0)
        ]
        coclass PSeqGen
        {
    interface IPSeqGen;
    [default] interface IUnknown;
        };
    }
    编译生成一个tlb文件,这个才是真正编译程序代码需要引入的接口声明文件。
    后面有很多事情要做,当然ATL的路上不会一路平坦的。
    多接触几次就会了
      

  24.   

    你接口定义的函数,你没有在cpp中实现,所以link出错
      

  25.   

    回复libinfei8848(26楼): 我试过类似的方法,你这样我也试了下,没搞定,能否再详细说说,我觉得我关键是细节不知哪做错了。回复gw_net(27楼): 是,但也不全对,他指的是没有找到旧的idl生成的Lib各位不要管什么分数了,只有给我讲明白,我单独开贴给分。有没有新旧idl替换的道理搞明白的,也出来露个头,给讲讲,就算不为分数,就当提携后进也行吧。还是那句话,如果是因为分数,就没意思了,只要我懂了,开贴另给,要多少给多少,还不行吗?
      

  26.   

    新建atl工程,添加对象在新的idl中import 给的idl然后你的对象修改基类,为需要实现接口的idl文件。比如原来的
    interface IXXXX : IDispatch
    改为
    interface IXXXX : IMainIdlMethod
    就可以了
    自己实现,具体的方法
      

  27.   

    杨老师COM组件
    推荐你去网上找了,看看,讲解的比较通俗易懂
      

  28.   


    照着做了 NewATL(我的项目名) projec 编译通过,NewATLPS 如下错误:
    Error 1 error LNK2001: unresolved external symbol _IID_IMainIdlMethod NewATL_p.obj NewATLPS
    Error 2 fatal error LNK1120: 1 unresolved externals DebugPS\NewATLPS.dll NewATLPS
    这什么问题?
    另外 去领分 到:
    http://topic.csdn.net/u/20101025/11/365953c8-b267-4912-86f8-7ad82783a30e.html