VB6事件传递bool参数,在C#中始终为“true” [英] VB6 event passing bool argument that's always 'true' in C#

查看:248
本文介绍了VB6事件传递bool参数,在C#中始终为“true”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题很简单,我在VB6库中声明一个事件,该事件会传出一个布尔参数:

 公共事件WriteComplete(ByVal aCommsOk As Boolean,ByVal aBadPIN As Boolean)

我已经把我的c#代码挂上了事件很多次,但奇怪的是我的测试部门和一些其他ppl已经注意到,虽然VB6引发这个事件与aBadPIN设置为false,c#事件处理程序接收它为真。这是不一致的,所以它是'那些'的问题,但我没有找到任何东西在互联网上帮助很多。



我发现如果我定义一个将bool转换为一个字节的新事件,然后将其发送到c#中,那么这会解决这些问题问题机器。但是,我真的不想这样做,因为我必须为我的COM和.Net库之间的每一个bool进行修改(而且还有很多)。



我还读到某个地方有一个已知的错误(至少在C ++中),你必须强制EAX寄存器255来正确地表示错误,但是我从来没有遇到过这个问题,而且坦白地说不知道在VB6中开始做什么。



任何想法都会很棒!



更新:记录已经表明,当这个问题发生时,引发事件的调用将在c#事件处理程序触发之前将控件返回给VB6代码。这是什么?



更新:在提升代码退出后仍然看到事件处理程序接收事件,但尝试将更改更改为无效。时间限制将迫使我难以添加一个包装。

解决方案

对不起,问题不像bit-wise Boolean那么简单在VB6世界中的东西。



如果问题是编组的话,.NET可能会产生与其各自的VB6 DLL不同步的interop DLL? (除此之外,您是否熟悉VB6中的二进制兼容性设置?)



对于笑声,我做了以下操作 - 请让我知道,如果这个简单的项目是您正在跟踪的编码或编组问题的代表性模型。如果这个问题正在编组,通过c#和vb6项目的简化版本进行跟踪可能会有所帮助。



使用VB6,我创建了一个简单的ActiveX DLL(项目名为LibBoolBuster),一个名为BoolBuster的类:

 公共事件WriteComplete(ByVal aCommsOk As Boolean,ByVal aBadPIN As Boolean )

Public Sub DoIt(ByVal Mode As Integer)
RaiseEvent WriteComplete(CBool​​(Mode And 1),CBool​​(Mode And 2))
End Sub

使用VS2003(旧.NET,但仍然适用),我创建了一个简单的C#Windows应用程序,按钮,并参考上述VB6 ActiveX DLL。我以访问VB6 DLL的形式成员:

  public LibBoolBuster.BoolBuster vb6Obj = new LibBoolBuster.BoolBuster(); 

通过Interop的DLL是LibBoolBuster; BoolBuster类有事件和DoIt成员。在表单初始化中,事件联接完成如下:

  vb6Obj.WriteComplete + = new LibBoolBuster .__ BoolBuster_WriteCompleteEventHandler(vb6Obj_WriteComplete); 

WriteComplete事件处理程序是以下形式的成员:

  private void vb6Obj_WriteComplete(System.Boolean aCommsOk,System.Boolean aBadPIN)
{
MessageBox.Show(aCommsOk.ToString()+, + aBadPIN.ToString());
}

每个按钮点击事件处理程序都可以简单地调用DoIt:

  vb6Obj.DoIt(0); 

(和vb6Obj.DoIt(1),vb6Obj.DoIt(2)等) p>

非常简单的项目:点击一个按钮,DoIt被调用,事件WriteComplete被触发。我试了一下,事情按预期工作。






仔细看看VB6一面。你表示事件被提出:

  RaiseEvent WriteComplete(aCommsReceived,not(aIsAcknowledged))

确保aIsAcknowledged只有0或-1;否则你不会得到你期待的结果。



VB6布尔运算符都是按位;即,(不是1)导致-2不为零。



此外,在VB6中,从整数转换为布尔时,任何非零整数都将映射为True - 仅零变成假。


My problem is simple, I have an event declared in a VB6 library that passes out a boolean argument:

Public Event WriteComplete(ByVal aCommsOk As Boolean, ByVal aBadPIN As Boolean)

I have hooked my c# code up to this event many times but bizarrely my testing department and a couple of other ppl have noticed that although VB6 raises this event with aBadPIN set to false, the c# event handler receives it as true. It is not consistent so it's one of 'those' problems but I'm not finding anything on the internet to help much.

I have found that if I define a new event that converts the bool to a byte and sends that, then it's converted back in the c#, this fixes the issue on those problem machines. However, I really don't want to have to do that since I would have to do it for every single bool that gets marshaled between my COM and .Net libraries (and there's a lot of them).

I also read somewhere that there's a known bug (at least in C++) where you have to force the EAX register to 255 to properly represent false but I've never had this problem before and frankly wouldn't know where to start doing that in VB6 anyway.

Any ideas would be great!

Update: Logging has shown that when this issue occurs the call that raises the event returns control to the VB6 code before the c# event handler fires. What is up with that?

Update: Still seeing event handler receiving event after the raising code has exited but tried marshaling changes to no avail. Time constraints will force me to add a wrapper sadly.

解决方案

Sorry that the problem wasn't as simple as bit-wise Boolean stuff in VB6 world.

If the problem is marshalling, is it possible that the interop DLL that .NET makes is somehow out of sync with its respective VB6 DLL? (As an aside, are you familiar with the Binary Compatibility settings in VB6?)

For the giggles, I did the following - please let me know if this simple set of projects is a representative model for the coding or marshalling issue you are tracking. If this issue is marshalling, it might be helpful to work it through simplified versions of the c# and vb6 projects in tracking it down.

With VB6, I created a simple ActiveX DLL (project named LibBoolBuster), with a class called BoolBuster:

Public Event WriteComplete(ByVal aCommsOk As Boolean, ByVal aBadPIN As Boolean)

Public Sub DoIt(ByVal Mode As Integer)
    RaiseEvent WriteComplete(CBool(Mode And 1), CBool(Mode And 2))   
End Sub

With VS2003 (old .NET, but should still apply), I created a simple C# Windows app, having a form with four buttons, and making reference to the above VB6 ActiveX DLL. I made a member in the form that accesses the VB6 DLL:

public LibBoolBuster.BoolBuster vb6Obj = new LibBoolBuster.BoolBuster();

DLL via Interop is LibBoolBuster; class BoolBuster has event and DoIt member. In the form initialize, the event hookup is done like so:

vb6Obj.WriteComplete += new LibBoolBuster.__BoolBuster_WriteCompleteEventHandler(vb6Obj_WriteComplete);

The WriteComplete event handler is a member of the form:

private void vb6Obj_WriteComplete ( System.Boolean aCommsOk  , System.Boolean aBadPIN )
{
    MessageBox.Show(aCommsOk.ToString() + ", " + aBadPIN.ToString());           
}

Each button click event handler makes a simple call to DoIt:

vb6Obj.DoIt(0);

(and vb6Obj.DoIt(1), vb6Obj.DoIt(2), etc.)

Very simple project: Click a button, DoIt is called, event WriteComplete is fired. I gave it a try, and things worked as expected.


Take a close look on the VB6 side. You indicated the event is raised with:

RaiseEvent WriteComplete(aCommsReceived, Not (aIsAcknowledged))

Make sure that aIsAcknowledged is only either 0 or -1; otherwise you will not get the result you're expecting.

VB6 Boolean operators are all bitwise; i.e. (Not 1) results in -2 not zero.

Also, in VB6 any non-zero integer will be mapped to True when converting from Integer to Boolean - only zero becomes false.

这篇关于VB6事件传递bool参数,在C#中始终为“true”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆