討論區快速選單
知識庫快速選單
討論區最近新進100則主題 掌握Salesforce雲端管理秘訣
[ 回上頁 ] [ 討論區發言規則 ]
跨apartment的元件使用出現錯誤
更改我的閱讀文章字型大小
作者 : fancy(8086) 人氣指數超過10000點
[ 貼文 95 | 人氣 19471 | 評價 0 | 評價/貼文 0 | 送出評價 8 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/1/15 上午 01:22:17
小弟改了一個在處理中伺服器的組件,主執行緒為MTA,但是DLL 元件的
ThreadingModel="" 或 沒有 , 因此呼叫 CoGetClassObject/
CoCreateIntance[Ex]COM會自動建立Main STA(STA0),CoGetClassObject
調用得到的類場對象(proxy)沒問題,但是再調用類場的CreateIntance卻發生了 REGDB_E_IIDNOTREG 錯誤. 或是直接調用CoCreateIntance 是 E_NOINTERFACE 錯誤 , 不知是哪個環節出了錯誤 .

http://support.microsoft.com/kb/150777/zh-tw

上面這個網只有指出apartment與object使用關係 , 而我上面的情況就是

用戶端 伺服器 結果
------ ------ -----------------------------------------------------
MTA 無 proxy存取;伺服器載入到STA0;如果必要STA0由COM自動建立

不知哪為大大能否說明上面這個模式的正確做法 , 或是我漏了哪個步驟~~

程式碼在此: http://myweb.fcu.edu.tw/~d9147897/InProc.rar

主要是輸入2數到元件中再作相加並回傳到 client. 有問題步驟是卡在第2歨驟 ,
若把主執行緒中的CoInitializeEx(NULL,COINIT_MULTITHREADED);改成
CoInitialize(NULL); 是沒問題的 , 所產生的元件沒有 PROXY可以直接調用
因為在只執行緒的STA中.


0. 先編譯 AddObj 產生DLL 再編譯 VCClient 執行.
1. 顯示 MTA 和 STA 執行緒 ID , 表示確實有2個apartment存在 , MTA是由COM所建立
2. CAddObj 的確有被創建 , 但是呼叫 pFactory->CreateInstance 或
   CoCreateInstance 所得到的 proxy 指標卻為 null , 問題就是在這.
3. 輸入 2數 並傳回結果

在此感激不進!! 靠大家了~~
作者 : fancy(8086) 人氣指數超過10000點
[ 貼文 95 | 人氣 19471 | 評價 0 | 評價/貼文 0 | 送出評價 8 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/1/16 下午 02:18:38
終於找到答案了. 分享一下

由於一般我們都使用客戶端和組件都在相同 apartment 中根本不會有 proxy/stub.
但是當跨進程 跨套間 就會有 proxy/stub.
沒錯~ 當呼叫 CoGetClassObject/CoCreateIntance[Ex] 時 COM庫
的確會為我們自動列集接口指針散集到客戶 proxy , 但是問題COM
庫不知道我們的接口定義因此無法列集接口指針.


方式1:
使用 proxy/stub dll
假設為 server.idl , 要產生 proxystub.dll:
(0) midl 編譯 server.idl
(1) 建立一个WIN32的DLL "空" 的工程。 不需有 DllMain.
(2) 把 server.h,server_i.c,server_p.c和dlldata.c加入工程
(3) 建立一个PROXYSTUB.def,一定要加入工程
    内容如下:

    LIBRARY PROXYDEF.dll
    DESCRIPTION 'proxy/Stub Dll'
    EXPORTS
     DllGetClassObject PRIVATE
     DllCanUnloadNow PRIVATE
     GetProxyDllInfo PRIVATE
     DllRegisterServer PRIVATE
     DllUnregisterServer PRIVATE

在工程的setting里加上_WIN32_DCOM,REGISTER_PROXY_DLL和rpcrt4.lib
然后编译连接,我想回通过的 , 若出現 "errorc1010:unexpected end of file while looking for precompiled header directive" , 选择setting,在c/c++栏,选择PreCompiled headers,然后设置第一选项,选择不使用预编译头,解决这个问题。

    是否有注意到 , 我們沒定義 DllMain DllGetClassObject DllCanUnloadNow GetProxyDllInfo DllRegisterServer DllUnregisterServer
    這些函數 , 竟然可以產生 dll !! 這是怎麼一回事 ? 原來 REGISTER_PROXY_DLL 這個巨集就是把這些定義給加入進來的~~

(4) regsvr32 proxystub.dll

方式2: 使用 .tlb
(1) 在直接使用类型库时,应首先将类型库装载到内存,这可以通过多种方式进行。对于已注册到注册表中的类型库,可以使用LoadRegTypeLib()装载。如果知道类型库的准确路径也可以通过LoadTypeLib()函数直接从磁盘装载,并在装载成功后需要调用RegisterTypeLib()完成在注册表中的注册 ; 或是使用 LoadTypeLibEx(...,REGKIND_REGISTER)
可以直接裝載並註冊。

(2) idl 接口屬性的 [oleautomation] 設置

當呼叫 LoadTypeLibEx(...,REGKIND_REGISTER) 或 RegisterTypeLib()
註冊類型庫後 , 會產生以下幾個註冊鍵:
HKEY_CLASSES_ROOT\Interface\{IID}\ProxyStubClsid\default HKEY_CLASSES_ROOT\Interface\{IID}\ProxyStubClsid32\default HKEY_CLASSES_ROOT\Interface\{IID}\Typelib\default

oleaut32.dll , 它本身也是封送拆收器 , 但是它是类型库封送拆收器需要類型庫.
代理和存根同样是COM对象,系统提供了一个缺省的存根和代理,它们实现在 oleaut32.dll 中,对于大多数的列集处理来说,缺省的存根和代理已经足够用了,但它只能列集那些自动化兼容的数据类型的参数。 因此我們提供的類型庫也要有自动化兼容的数据类型的参数 , 而接口屬性的 [oleautomation] 設置好可以如此.
 板主 : 徵求中
 > COM/DCOM - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - COM/DCOM - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
COM/DCOM
1 估得 490 
2 nick 120 
3 PLAYER 110 
4 天雲 100 
5 Raynor 80 
6 青衫 60 
7 60 
8 Peter.huang 50 
9 酷小毅 50 
10 Giant 50 
COM/DCOM
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
1.611328E-02