什么时候才需要用到代理/存根? 好像没有这个dll,com组件也可以被创建啊?

时间:2021-05-04 16:01:30
如题,我建立一个atl的工程,接受所有的默认选项,于是建立了一个易于dll的com组件。我增加了一个atl简单对象叫做my。
ide为我生成了两个工程,一个是com组件本身,一个是PS工程(代理/存根)。我删掉了这个PS‘工程。

然后我建立一个命令行工程,在main.cpp里面#import我的atl工程生成的tlb,创建my的com对象,调用其函数,没问题,一切OK。

那我的问题来了----这里看起来我的调用过程没有依赖任何代理/存根这个工程生成的东西(因为我已经删除了这个工程)。

那么
(1) 这个PS工程的存在的意义到底是什么
(2) 什么情况下,我必须依赖代理/存根才能完成某些事情呢? 是跨机器的dcom还是什么? 

我感觉本机调用com dll的工程,好像根本就用不上所有的代理和存根。

7 个解决方案

#1


自己顶一下。。。。。。。

#2


如果通过import,注册com组件方式,那么就可以不需要ps来调用

#3


引用 2 楼 oyljerry 的回复:
如果通过import,注册com组件方式,那么就可以不需要ps来调用

是的,我就是编译完了com组件以后有注册,然后在我的工程里面通过#import来调用。

你的意思是,可以不注册这个com组件? 在我的应用程序里面也不用import这个tlb? 只需要调用p/s这个dll,我就能和com组件通信了。是这样的吗?

谢谢。

#4


跨进程调用需要代理,和存根

#5


引用 4 楼 hdt 的回复:
跨进程调用需要代理,和存根


不是啊。我做了一个实验。我
1. 建立了一个ATL工程叫做ATLProject2,立刻删除相应的PS工程及其所有文件。
2. 给ATL工程添加一个简单的ATL对象叫做My,给My增加一个函数叫做Func,代码如下:

STDMETHODIMP CMy::Func(int i, int* o)
{
    // TODO: Add your implementation code here
    *o = i + 1;
    return S_OK;
}

然后我写一个控制台程序:

#import "..\ATLProject2\Debug\ATLProject2.tlb" no_namespace
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IMyPtr p;
p.CreateInstance(__uuidof(My), NULL, CLSCTX_ALL);
        int i = p->Func(1);
        cout << i << endl;
CoUninitialize();
return 0;
}

程序打印输出2,如我的预期。所以看起来即使是跨进程调用(我的com是个exe),仍然可以不需要代理/存根?

不知道我的理解有没有问题,还请指教

#6


引用 3 楼 sadsaer 的回复:
Quote: 引用 2 楼 oyljerry 的回复:

如果通过import,注册com组件方式,那么就可以不需要ps来调用

是的,我就是编译完了com组件以后有注册,然后在我的工程里面通过#import来调用。

你的意思是,可以不注册这个com组件? 在我的应用程序里面也不用import这个tlb? 只需要调用p/s这个dll,我就能和com组件通信了。是这样的吗?

谢谢。

我是说如果注册了,同时你程序又用的import方式,那么就不需要PS了
但是有很多情况,程序不会用import方式,那么就通过ps来做

#7


只有跨进程,才会需要代理和存根,代理和存根,对于用户来说是透明的,也就是说你不会感觉它的存在

#1


自己顶一下。。。。。。。

#2


如果通过import,注册com组件方式,那么就可以不需要ps来调用

#3


引用 2 楼 oyljerry 的回复:
如果通过import,注册com组件方式,那么就可以不需要ps来调用

是的,我就是编译完了com组件以后有注册,然后在我的工程里面通过#import来调用。

你的意思是,可以不注册这个com组件? 在我的应用程序里面也不用import这个tlb? 只需要调用p/s这个dll,我就能和com组件通信了。是这样的吗?

谢谢。

#4


跨进程调用需要代理,和存根

#5


引用 4 楼 hdt 的回复:
跨进程调用需要代理,和存根


不是啊。我做了一个实验。我
1. 建立了一个ATL工程叫做ATLProject2,立刻删除相应的PS工程及其所有文件。
2. 给ATL工程添加一个简单的ATL对象叫做My,给My增加一个函数叫做Func,代码如下:

STDMETHODIMP CMy::Func(int i, int* o)
{
    // TODO: Add your implementation code here
    *o = i + 1;
    return S_OK;
}

然后我写一个控制台程序:

#import "..\ATLProject2\Debug\ATLProject2.tlb" no_namespace
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IMyPtr p;
p.CreateInstance(__uuidof(My), NULL, CLSCTX_ALL);
        int i = p->Func(1);
        cout << i << endl;
CoUninitialize();
return 0;
}

程序打印输出2,如我的预期。所以看起来即使是跨进程调用(我的com是个exe),仍然可以不需要代理/存根?

不知道我的理解有没有问题,还请指教

#6


引用 3 楼 sadsaer 的回复:
Quote: 引用 2 楼 oyljerry 的回复:

如果通过import,注册com组件方式,那么就可以不需要ps来调用

是的,我就是编译完了com组件以后有注册,然后在我的工程里面通过#import来调用。

你的意思是,可以不注册这个com组件? 在我的应用程序里面也不用import这个tlb? 只需要调用p/s这个dll,我就能和com组件通信了。是这样的吗?

谢谢。

我是说如果注册了,同时你程序又用的import方式,那么就不需要PS了
但是有很多情况,程序不会用import方式,那么就通过ps来做

#7


只有跨进程,才会需要代理和存根,代理和存根,对于用户来说是透明的,也就是说你不会感觉它的存在