我们有一个基于.NET 4的服务,它通过回调自托管WCF服务。我们将此服务封装在公开COM对象的.NET 4 dll中。这项服务被各种各样的客户使用,其中大多数是基于.NET的。
不幸的是我们有一些我们无法更改的VB6客户端,并且在调用某些回调方法时我们正在获取AccessViolationExceptions。
服务的结构方式是回调,如下所示。
MethodA 由VB6客户端调用,通过.NET dll代理到WCF服务(尚未返回)
WCF CallbackA 调用提供枚举状态值
可能会调用WCF CallbackB ,需要VB6客户端的进一步输入(此信息无法在MethodA的开头获得并影响MethodA的结果)
MethodA 返回
CallbackA (效果很好,没有异常!)它是一个提供Enum的OneWayOperation,VB应用程序当前正在将此值写入RichTextbox。
CallbackB (导致AccessViolationException)是一个提供对象的方法,并期望一个不同的对象返回两个基于值的属性。
我觉得这是尝试在与主线程不同的线程上创建COM对象的某种问题(因为它当前挂在MethodA上)。不幸的是我不知道如何纠正这个问题。我们可以控制服务中的代码,封装dll,我们可以建议VB6客户端中的代码。
我们有自己的VB6测试应用程序,我们可以绕过AccessViolation错误....但它涉及注释掉回调方法中的任何代码(参见下面的代码)我已经突出显示导致异常的行如果保留"< -----导致异常"。非常感谢任何帮助,如果您需要更多信息,请告诉我。
Private Function ITerminalCallbackComClient_VerifySignature() As Long
Dim result As Long
'Not-Authorized = 0 and Authorized = 1'
result = 0
Dim msgResponse As Long
msgResponse = MsgBox("Signature Accepted?", vbYesNo + vbQuestion, "Signature Verification")
If msgResponse = vbYes Then
result = 1
End
End If
ITerminalCallbackComClient_VerifySignature = result
End Function
更新2014-11-13
回调在Visual Studio 6中调试时有效。但是,只要我们"制作"示例项目在执行回调时崩溃。如果我们删除对MsgBox的引用并仅映射回静态值,它将按预期工作。
我们已将Signature更新为COM Interop以删除所有对象引用,而不只是返回0或1以避免对象命名问题。
我已经更新了上面的VB6回调代码。
回调合约
[CallbackBehaviorAttribute(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public abstract class PS_Terminal_Link_Callback : ITerminalCallback
{
public abstract long VerifySignature();
}
服务合同
[ServiceContract(CallbackContract=typeof(ITerminalCallback))]
public interface ITerminal
{
*MethodA*
}
答案 0 :(得分:0)
如果是VB6代码,则LONG是VB6中的win32整数。对于16位基本整数的兼容性,VB6中为16位。多头是32位。您将VB6长(32位)放入消息框行中的VB6整数(16位)。
您的其他对象是私密的,因此我们无法查找其规格和文档。
答案 1 :(得分:0)
您也可以从调试器开始。
windbg或ntsd(ntsd是一个控制台程序,可能已安装)。两者都来自Windows调试工具。
下载并安装适用于Windows的调试工具
http://msdn.microsoft.com/en-us/windows/hardware/hh852363
安装Windows SDK,但只需选择调试工具。
在** C:**
中创建名为符号的文件夹启动Windbg。 文件菜单 - 符号文件路径并输入
srv*C:\symbols*http://msdl.microsoft.com/download/symbols
然后
windbg -o -g -G c:\windows\system32\cmd.exe /k batfile.bat
您可以按F12
停止它,kb
将显示调用堆栈(g
继续程序)。如果有错误,它也会停止并显示它们。
键入lm
列出已加载的模块,x *!*
列出符号,bp symbolname
设置断点
如果在VB6中编程,则此环境变量link = / pdb:none将符号存储在dll中而不是单独的文件中。确保使用No Optimisations编译程序并勾选Create Symbolic Debug Info框。两者都在项目属性的“编译”选项卡上。
CoClassSyms(microsoft.com/msj/0399/hood/hood0399.aspx)也可以从类型库中创建符号。
在COM调用上放置一个断点(使用x *!*
来查找它)。
现在您可以检查参数和/或查看详细的异常信息。