Silverlight-DLL通信问题

时间:2012-08-29 06:54:14

标签: wcf silverlight

Silverlight 4应用程序的问题。 在此应用程序中,每个客户端会话都会创建一个单独的进程,该进程调用DLL。

与DLL的通信构建如下面的callstack(对于两个函数:一个工作,另一个 - 不是。)

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;
    }

然后 - 在lambda表达式中:

    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;
    }

由于服务器端引发了异常,因此省略了客户端通信。 GetPageDividions函数工作正常,错误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,PageNum); 同     DocDividionsResult br = WPService.GetPageDividions(docID,formId,pageNumber); 然后没有抛出异常。

1 个答案:

答案 0 :(得分:1)

不确定您是否从一开始就开始,但我希望您发布的所有代码都不会导致错误。该错误意味着您无法从客户端调用Web服务(Silverlight),因为Web配置中的system.serviceModel部分中存在错误。您通常只需刷新服务参考即可解决此问题。

尝试在visual studio中本地运行应用程序并将服务引用指向您在服务器上安装的服务(右键单击服务引用并选择配置服务引用,然后将URl更改为与服务器上的服务位置相对应) 。如果您已在此配置中开发/测试,请尝试右键单击服务引用并选择“更新服务引用”。