非常感谢各位的帮助,编译时找不到CoInitializeEx()的定义的问题已经解决。但在运行的过程中我又遇到了这样的问题:现在的情况是:在同一个DLL中实现了A,B,C,D四个COM组件,其中,A的一些方法中会调用B,C,D三个组件;A的一个方法中会生成一个新的线程ThreadT,这个线程要求与A的各方法同时调用B,C,D三个组件。有一个单线程的EXE会调用到A,B,C,D四个组件.这个EXE在运行中会调用A的那个方法,生成线程ThreadT。这样,在这个EXE的运行过程中,就会要求EXE本身,组件A的一些方法,以及线程ThreadT能够同时访问B,C,D三个组件。现在的问题是:应该在哪里使用CoInitializeEx(),使用哪个参数呢?已经做过的试验:
1、在DLL的InitInstance()函数中和线程ThreadT的主函数中调用CoInitializeEx()函数,都使用 COINIT_MULTITHREADED 参数,结果是:前者返回RPC_E_CHANGED_MODE ,后者返回 S_OK 。2、在DLL的InitInstance()函数中和线程ThreadT的主函数中调用CoInitializeEx()函数,都使用 COINIT_APARTMENTTHREADED 参数,结果是:前者返回S_FALSE ,后者返回 S_OK 。现在看来,在DLL的app对象初始化之前,CoInitializeEx()已经被调用过了,使用COINIT_APARTMENTTHREADED 函数。我的疑惑在于:为什么在ThreadT中调用CoInitializeEx()时,为什么没有检测到已经存在的套间,却返回S_OK呢?肯请大虾指点!!!!!!!
现在程序的时间反正也延误了,干脆慢慢找解决办法吧,呵呵。

解决方案 »

  1.   

    每个要调用COM组件的线程都必须调用!只要在调用前调用就行了
      

  2.   

    那么应该使用哪个参数呢?现在要求在某个要调用B,C,D的方法返回之前,线程ThreadT就能够同时访问B,C,D。在EXE的AFXOleInit()函数中,应该已经使用COINIT_APARTMENTTHREADED 初始化了吧?那么,之后的调用如果使用其他参数,会不会返回
    RPC_E_CHANGED_MODE 呢?
      

  3.   

    十分感谢,我想现在对于这个问题有了一个比较清楚的认识。现在又出现了这样的问题,这可能跟前面的问题无关:
    在主线程中调用CoInitializeEx,初始化为MTA模式,结果在主线程访问组件A的时候,出
    现了有的方法可以正常访问,有的方法却不能访问,系统会报这样的错:
    First-chance exception in MDemo.exe (OLE32.DLL): 0xC0000005: Access Violation.First-chance exception in MDemo.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ 
    Exception.访问出错的这个方法使用三个LPUNKNOWN型指针传递参数,
    访问没有出错的方法使用两个long型参数。不知能不能看出是哪里的问题?
      

  4.   


    太复杂了,简直象在讲绕口令。我的建议,把A,B,C,D放在不同的DLL中分别实现。为了能够让多线程访问一个OCX,建议ABCD每个组件中都没有全局变量或者静态变量。不要让组件创建一个线程供EXE使用,否则你设计的这个组件简直是白忙活。因为很多语言中并没有显式的线程的概念。线程并不是IDL的一个部分。
    如果要那样做,把这个线程写成C++的动态库好了。
      

  5.   

    谢谢各位,问题解决了,但却不是正面解决。我只是想办法没有在ThreadT中调用组件。至于多线程访问的问题,仍然没有得到解决。对于eastsun兄的意见,现在的情况是:把a,b,c,d放在同一dll正是我们的目的;现在组件创建了线程,但exe并不使用这个线程,只是组件在用。还有一个重要的问题是我们的组件现在还不能保证是线程安全的。