2012-08-29 32 views
0

Silverlight 4應用程序的問題。 在這個應用程序中,每個客戶端會話創建一個獨立的進程,它調用一個DLL。Silverlight-DLL通信問題

與DLL的通信建立在以下調用堆棧中(對於兩個函數:一個工作,另一個 - 不)。

有2個函數的DLL(都工作得不錯):

extern "C" BOOL __stdcall DocRunExternPageDividions(const char *docId, int num_form, int PageNum, int *Vcols, int **Vvalues, int *Hcols, int **Hvalues) 
{ 
    LOG_START_FUNCTION 
    BOOL res = 1; 
    __try { 
     res = DocRunExternPageDividions1(docId, num_form, PageNum, Vcols, Vvalues, Hcols, Hvalues); 
    } 
    __except(ExFilter(GetExceptionInformation())) 
    { 
     AfxThrowUserException(); 
    } 
    LOG_STOP_FUNCTION 
    return res; 
} 


extern "C" BOOL __stdcall DocRunExternPageBreakRects(const char *docId, int num_form, int PageNum) 
{ 
    LOG_START_FUNCTION 
     BOOL res = 1; 
    __try { 
     res = DocRunExternPageBreakRects1(docId, num_form, PageNum); 
    } 
    __except(ExFilter(GetExceptionInformation())) 
    { 
     AfxThrowUserException(); 
    } 
    LOG_STOP_FUNCTION 
     return res; 
} 

要調用這個函數服務器有兩個代表:

private delegate void DocRunExternPageBreakRectsDelegate(string docId, int DocNum, int PageNum); 

private delegate void DocRunExternPageDividionsDelegate(
    string docId, int DocNum, int PageNum, out int Vcols, out IntPtr VoutArray, out int Hcols, 
    out IntPtr HoutArray); 

...兩個委託實例和對應功能:

private DocRunExternPageBreakRectsDelegate DocRunExternPageBreakRectsD; 
       DocRunExternPageBreakRectsD = 
       Marshal.GetDelegateForFunctionPointer(ptrDocRunExternPageBreakRects, 
                 typeof (DocRunExternPageBreakRectsDelegate)) as 
       DocRunExternPageBreakRectsDelegate; 

    private DocRunExternPageDividionsDelegate DocRunExternPageDividionsD; 
       DocRunExternPageDividionsD = 
       Marshal.GetDelegateForFunctionPointer(ptrDocRunExternPageDividionsD, 
                 typeof (DocRunExternPageDividionsDelegate)) as 
       DocRunExternPageDividionsDelegate; 

    public void DocRunExternPageDividions(string docId, int DocNum, int PageNum, out int[] vert, out int[] horz) { 
     IntPtr VoutArray, HoutArray; 
     int vcols, hcols; 
     DocRunExternPageDividionsD(docId, DocNum, PageNum, out vcols, out VoutArray, out hcols, out HoutArray); 
     marshal(VoutArray, out vert, vcols); 
     marshal(HoutArray, out horz, hcols); 
    } 

    public void DocRunExternPageBreakRects(string docId, int DocNum, int PageNum) { 
     DocRunExternPageBreakRectsD(docId, DocNum, PageNum); 
    } 

在這裏調用這些函數(服務器代碼):

public bool PageBreakRects(string docId, int DocNum, int PageNum, out int[] vert, out int[] horz) { 
     bool result; 
     vert = null; 
     horz = null; 
     Program.WriteUserMessage("Called PageBreakRects(" + docId + ", " + DocNum + ", " + PageNum + ")"); 
     try { 
      DocRunExternPageBreakRects(docId, DocNum, PageNum); 
      DocRunExternPageDividions(docId, 0, PageNum, out vert, out horz); 
      result = true; 
     } catch (Exception ex) {} 
     return result; 
    } 

    public bool GetPageDividions(string docID, int Id, int pageNumber, out int[] vert, out int[] horz) { 
     bool result = false; 
     vert = null; 
     horz = null; 
     try { 
      DocRunExternPageDividions(docID, Id, pageNumber, out vert, out horz); 
      result = true; 
     } catch (Exception) {} 
     return result; 
    } 

他們每個人 - 在這裏稱爲:

public DocDividionsResult PageBreakRects(string docID, int DocNum, int pageNumber) { 
     var result = new DocDividionsResult(); 
     int[] vert; 
     int[] horz; 
     result.Data = new List<object> { Program.DllWrapper.PageBreakRects(docID, DocNum, pageNumber, out vert, out horz) }; 
     result.Vert = vert; 
     result.Horz = horz; 
     return result; 
    } 

    public DocDividionsResult GetPageDividions(string docID, int formId, int pageNumber) { 
     var result = new DocDividionsResult(); 
     int[] vert; 
     int[] horz; 
     result.Data = new List<object> 
         {Program.DllWrapper.GetPageDividions(docID, formId, pageNumber, out vert, out horz)}; 
     result.Vert = vert; 
     result.Horz = horz; 
     return result; 
    } 

然後 - 拉姆達表達式中:

public bool GetPageDividions(string docID, int formId, int pageNumber, out int[] vert, out int[] horz) { 
     bool result = false; 
     int []localVert = null; 
     int []localHorz = null; 

     if (_wp != null) { 
      if (Service<IWPCommunication>.Use(TestService => 
      { 
       TestService.Test(UserId); 
      }, 
      WPService => 
      { 
       DocDividionsResult br = WPService.GetPageDividions(docID, formId, pageNumber); 
       if (br != null && br.Data != null && br.Data.Length == 1) 
       { 
        result = (bool)br.Data[0]; 
        localVert = br.Vert; 
        localHorz = br.Horz; 
       } 
      }, Id, FS) == 0) 
      { 
     ... 
       result = false; 
      } 
     } 
     vert = localVert; 
     horz = localHorz; 
     return result; 
    } 

    public bool PageBreakRects(string docId, int DocNum, int PageNum) { 
     bool result = false; 
     if (_wp != null) 
     { 
      if (Service<IWPCommunication>.Use(TestService => 
      { 
       TestService.Test(UserId); 
      }, 
      WPService => 
      { 
       DocDividionsResult br = WPService.PageBreakRects(docId, DocNum, PageNum); 
       if (br != null && br.Data != null && br.Data.Length == 1) { 
        result = (bool)br.Data[0]; 
       } 
      }, Id, FS) == 0) 
      { 
     ... 
       result = false; 
      } 
     } 
     return result; 
    } 

「使用」 功能(以上使用):

public static int Use(UseServiceDelegate<T> codeTest, UseServiceDelegate<T> codeBlock, string SessionId, FileStream fs, bool throwException) { 
     IClientChannel texy = (IClientChannel)_testFactory.CreateChannel(new EndpointAddress("net.pipe://localhost/X2WPServiceUID" + SessionId)); 
     IClientChannel proxy = (IClientChannel)_channelFactory.CreateChannel(new EndpointAddress("net.pipe://localhost/X2WPServiceUID" + SessionId)); 
     int returnCode = 0; 
     try { 
      if (codeTest != null) { 
       codeTest((T)texy); 
       texy.Close(); 
      } 
      returnCode = 1; 
      if (codeBlock != null) { 
       codeBlock((T)proxy); 
       proxy.Close(); 
      } 
      returnCode = 2; 
     } catch(Exception e) { 
      if (returnCode == 1 && throwException) 
       throw e; 
     } finally { 
      if (returnCode == 0 && codeTest != null) 
       texy.Abort(); 
      else if (returnCode == 1 && codeBlock != null) 
       proxy.Abort(); 
     } 
     return returnCode; 
    } 

客戶端通信被省略,因爲在第e服務器端。 GetPageDividions函數工作正常,bug PageBreakRects - 不是:行 DocDividionsResult br = WPService.PageBreakRects(docId,DocNum,PageNum); 引發以下例外:

"The message with Action 'http://tempuri.org/IWPCommunication/PageBreakRects' 
cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. 
This may be because of either a contract mismatch (mismatched Actions between sender and receiver) 
or a binding/security mismatch between the sender and the receiver. 
Check that sender and receiver have the same contract and the same binding 
(including security requirements, e.g. Message, Transport, None)." 

更糟糕的是提的是,如果在功能PageBreakRects取代: DocDividionsResult BR = WPService.PageBreakRects(的docId,DocNum,頁次); DocDividionsResult br = WPService.GetPageDividions(docID,formId,pageNumber); 與 DocDividionsResult br = WPService.GetPageDividions(docID,formId,pageNumber); 則不會引發異常。

回答

1

不知道您是否已經開始使用,但我希望您發佈的任何代碼都不會導致錯誤。那個錯誤意味着你無法從客戶端調用你的webservice(silverlight),因爲web配置中的system.serviceModel部分存在錯誤。您通常可以通過刷新服務參考來修復它。

嘗試在Visual Studio本地運行應用程序,並將服務引用指向服務器上安裝的服務(右鍵單擊服務引用並選擇配置服務引用,然後更改URl以對應服務器上的服務位置)。如果您已經在此配置中開發/測試,請嘗試右鍵單擊服務參考並選擇「更新服務參考」。