用于导入的“RegExp.tlb”的 C++ COM 接口是不是在进程之间隐式共享内存?
Posted
技术标签:
【中文标题】用于导入的“RegExp.tlb”的 C++ COM 接口是不是在进程之间隐式共享内存?【英文标题】:Is C++ COM interface for imported "RegExp.tlb" implicitly sharing memory between processes?用于导入的“RegExp.tlb”的 C++ COM 接口是否在进程之间隐式共享内存? 【发布时间】:2013-08-12 16:44:16 【问题描述】:好时光。对不起,如果我的问题很奇怪,但我对我所面临的事情是新的。
我的情况如下,我通过 COM 在 C++ 中使用 VB RegExp 如下:
#import "RegExp.tlb" no_namespace
...
void DoSomething()
...
static IRegExpPtr regExp( __uuidof(RegExp) );
regExp->Pattern = A2BSTR(m_szStrReg); // read on dll load from the file
if ( regExp->Test(someString) )
IMatchCollectionPtr matches = regExp->Execute(someString);
// my staff here
...
...
我的问题是:
我做得对吗? (p.s. 我知道 CoInit 和 CoUninit,但问题不在于它们)。
regExp
进程安全吗? 我问这个的原因是因为我的班级有几个实例,DoSomething()
多次调用它。我在 regExp 内部有崩溃。由不同 args 的 regExp 方法的不同调用随机导致堆损坏/无效内存访问。
我检查了 regExp 指针值,regExp->Pattern.GetAddress() 等等。并且它们在不同的过程中是不同的。但是当我添加了名为 Mutex 并用它包装 DoSomething()
时,它添加了进程间同步 - 崩溃消失了。这就是为什么我要问 regExp 是否在进程之间隐式共享了一些东西?
【问题讨论】:
闻起来像你是多线程的,并且有多个线程使用单个 regExp 实例 这里似乎也有泄漏:regExp->Pattern = A2BSTR(m_szStrReg)
,假设Pattern
是_bstr_t
类型。另外,你真的是想让static IRegExpPtr regExp
成为静态的吗?
@pm100 不,同一进程中只有一个线程。
@Mihail, _bstr_t
确实使用SysAllocString
复制了传递的字符串。然而A2BSTR
也使用SysAllocString
(看看atlconv.h),这就是这行代码泄漏的地方。也许,你想要RegExp->Pattern = A2W(m_szStrReg)
?
@Noseratio 非常感谢您的通知!
【参考方案1】:
您的代码正在处理当前公寓中的 COM 接口指针。您已经知道 COM 初始化,因此如果您特别是在 STA 中,则当前单元意味着当前线程。您可以保证接口指针的方法是可调用的,但该接口指针的后端可能会有所不同:它可以是直接实现,也可以是一个辅助对象(代理),它将调用转移到实际对象所在的单元中.后者尤其可能在另一个进程中。
这是所有线程安全和“进程安全”的。参数通过对实际对象的调用获取,然后传回。调用者不必关心它是在处理真实对象还是代理,被调用者也不需要知道它是由实际调用者还是助手存根调用的。
话虽如此,上面的sn-p代码还是不错的。您遇到的崩溃肯定有其他原因。
【讨论】:
感谢您的回答!我是否正确理解我的两个进程可能同时将调用转移到驻留在一间公寓某处的实际正则表达式对象? 是的,这是可能的,但这取决于服务器的实现方式。您只显示很好的客户端代码。在服务器上,它可以是 STA 或 MTA 对象,MTA 对象可能是线程安全的或不安全的,它可能完全是单例的等等。这可能会导致您的问题。写得不好的 COM 服务器可能很容易造成这样的麻烦。以上是关于用于导入的“RegExp.tlb”的 C++ COM 接口是不是在进程之间隐式共享内存?的主要内容,如果未能解决你的问题,请参考以下文章