用atl写com组件,问题不怎么好说,具体见下,我在CGoLayers类中增加了一个接口方法如下:
STDMETHODIMP CGoLayers::Add(IGoLayer*layer, VARIANT_BOOL *pVal)
其中IGoLayer是我同一个dll中的另一个com类CGoLayer的接口。
现在我想在该Add方法中通过layer接口指针得到指向CGoLayer对象的指针,能不能得到?如何得到?

解决方案 »

  1.   

    可以的到,直接static_cast即可,因为你可以确保IGoLayer的实现者是CGoLayer,所以不成问题,但其他工程的就不应这样做,因为没人保证你IGoLayer的实现者的内存结构和CGoLayer一样,尤其跨语言就更不行了
      

  2.   

    我觉得你在Add方法中可以不用IGoLayer接口类型,而直接用CGoLayer类型来传递,具体是这样的:首先在CGoLayers类中定义一个CGoLayer指针类型的变量(如*p),然后修改CGoLayers类的构造函数,在其中加一个CGoLayer指针类型的变量,把它付值给p。在创建CGoLayers类的实例时再把CGoLayer的实例指针(this)传递进来就行了,比如你可以在CGoLayer类里增加一个方法用来创建CGoLayers类的实例。
      

  3.   

    用static_cast是不安全的,在很多情况下都会有问题。这里教你一个ATL的接口映射表技巧,来安全的实现你的要求。首先添加一个全局函数:
    inline HRESULT WINAPI _This(void* pv, REFIID id, void** ppObj, DWORD)
    {
    *ppObj = pv;
    return S_OK;
    };在CGoLayers类的接口映射表中添加一项:
    COM_INTERFACE_ENTRY_FUNC(IID_NULL, 0, _This)然后在Add函数中就可以这样取得this指针了:
    CGoLayers* pGoLayers = NULL;
    HRESULT hr = layer->QueryInterface(IID_NULL, (void**)&pGoLayers);
    if(SUCCEEDED(hr))
    {
      .......
    }
      

  4.   

    to GodenFluteSoftBoy(金笛秀才):
    因为IGoLayer接口是从IDispatch派生的,也就是IGoLayer是自动化的数据类型,
    这样做是因为做出来的组件能被vb,dephi,等其他面向对象语言和脚本语言调用的
    如果用CComObject<CGoLayer> *pGoLayer类型,除了vc之外,其他语言无法使用,做出
    来的控件也无法在脚本中使用,
    to  LeeZi(临渊羡鱼,不如退而结网):
    我写的这些接口也不是随便写的都是参考了arcInfo mo和mapInfo的MapX控件才写的,
    因此该接口方法是合理的,没有什么问题。
    谢谢你的回答!
      

  5.   

    to Analyst() :
    有点新意,我再想想,
    有谁做过比较大的地图控件(GIS),能暴露出对象层次模型给用户方便的进行二
    次开发,希望和你交朋友,聊天,谢谢,qq:65469645
      

  6.   

    CGoLayer* pCls=static_cast<CGoLayer*>(layer);
    要想作对象层次, 你需要作大量工作, 请看MSDN"ATL Collections and Enumerators", 比较复杂.