討論區快速選單
知識庫快速選單
政府補助!學嵌入式+物聯網 網路投保旅行平安險 2017必上資安技術訓練課程
[ 回上頁 ] [ 討論區發言規則 ]
MIDL.exe 編譯出來的 proxy/stub code 錯誤 ?
更改我的閱讀文章字型大小
作者 : fancy(8086) 人氣指數超過10000點
[ 貼文 95 | 人氣 19471 | 評價 0 | 評價/貼文 0 | 送出評價 8 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/1/30 上午 09:26:34
小弟使用 midl 編譯時 , 想產生 proxy/stub code 看一下 , 卻發現 vc6/8 的 code 一樣 , 但是實際呼叫
卻突然丟出例外 , 後來進去看一下 , 我在下面註解的地方就是好像 midl 產生錯了 , 總共有2種 ,
問題都是發生在一致性數組 , 固定數組或是多重指針的使用都沒問題.

(1) 內嵌指針為 [ref] , 會檢查所有內嵌指針是否為 NULL
 IDL:
import "oaidl.idl";
[
object,
uuid(61A1C81D-82CA-44e4-A60E-7BDD8E58A833),
pointer_default(ref)
]

interface IX:IUnknown
{
 
 typedef struct _Line
 {
  int x,y;
 }Line;

 HRESULT ARRAY(int size,[in,out,size_is(size)]Line* array[]);

};

proxy code:
HRESULT STDMETHODCALLTYPE IX_ARRAY_Proxy(
    IX __RPC_FAR * This,
    int size,
    /* [size_is][out][in] */ Line __RPC_FAR *__RPC_FAR *__RPC_FAR *__RPC_FAR array[ ])
{

    unsigned int _IM1;
    .....
    RpcTryExcept
    {
     .....

     //midl.exe 的 bug ? 應該是 for( _IM1 =0; _IM1 < size ; _IM1 = _IM1 + 1).
     //在 vc6 和 vc8 不知為啥結果都是如此 , vc8 預設的是 /Oicf 而 vc6 預設是產生 proxy/stub code.
     //若想在 vc8 產生 proxy/stub code , 編譯時使用 /Os 選項.
     for( _IM1 = 0;_IM1 < 0 + sizeof( Line __RPC_FAR *__RPC_FAR *__RPC_FAR *[ 1 ] );_IM1 = _IM1 + 1)
     {
     if(!array[_IM1])
     {
     RpcRaiseException(RPC_X_NULL_REF_POINTER);
     }
     if(!*array[_IM1])
     {
     RpcRaiseException(RPC_X_NULL_REF_POINTER);
     }
     if(!**array[_IM1])
     {
     RpcRaiseException(RPC_X_NULL_REF_POINTER);
     }
     }
     RpcTryFinally
     {
     .....

     //列集 size 參數加入到請求數據包 , 真實函數需要使用
     *(( int __RPC_FAR * )_StubMsg.Buffer)++ = size;

     //接口存根散集時需要使用
     _StubMsg.MaxCount = size;

     //列集 "一致性數組" 參數加入到請求數據包 , 其中 _StubMsg.MaxCount 已指明要列集此參數的應該大小.
     NdrComplexArrayMarshall( ...,array,...);
     .....
     }
     .....
    }
}

作者 : fancy(8086) 人氣指數超過10000點
[ 貼文 95 | 人氣 19471 | 評價 0 | 評價/貼文 0 | 送出評價 8 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/1/30 上午 09:27:10
(2) 內嵌指針傳遞方向為 [out] 因此服務器收到的是空的請求數據包要由某一參數來建立連續的頂級指針
IDL:
import "oaidl.idl";
[
object,
uuid(61A1C81D-82CA-44e4-A60E-7BDD8E58A833),
pointer_default(unique)
]

interface IX:IUnknown
{
 
 typedef struct _Line
 {
  int x,y;
 }Line;

 HRESULT ARRAY(int size,[in,out,size_is(size)]Line* array[]);

};

stub code:
void __RPC_STUB IX_ARRAY_Stub(
    IRpcStubBuffer *This,
    IRpcChannelBuffer *_pRpcChannelBuffer,
    PRPC_MESSAGE _pRpcMessage,
    DWORD *_pdwStubPhase)
{
    .....
    Line __RPC_FAR *__RPC_FAR *__RPC_FAR *( __RPC_FAR *array )[ ];
    int size;
    .....
    array = 0;
    RpcTryFinally
    {
     .....

    //把請求數據包中的列集函數 IX_ARRAY_Proxy 的 size 參數資訊給散集出來到 IX_ARRAY_Stub 的 size 參數
     size = *(( int __RPC_FAR * )_StubMsg.Buffer)++;
     .....

     //動態配置數組. 配置連續的頂級指針 ,
     array = NdrAllocate(&_StubMsg,size * 4);
    
     //midl 接下來沒有將每個元素內嵌指針初始為 null , 不知為啥 MIDL 沒有以下這一行 ? 其它情形都有.
     __MIDL_0010 = NdrAllocate(&_StubMsg,size * 4);
     .....
     }
     .....
}

不知大家有沒有預到上面那2種怪狀況 ? 第一種是客戶端呼叫可能會發生錯誤.
第2種會發生在服務端 , 服務端沒初始內嵌指針為 NULL. 之前的多重指針或固
定數組 stub code 都會初始 NULL.
 板主 : 徵求中
 > 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-2017 程式設計俱樂部 http://www.programmer-club.com.tw/
3.100586E-02