VB6 事件传递始终为“true”的布尔参数在 C# 中

发布于 2024-12-28 15:31:16 字数 689 浏览 1 评论 0原文

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

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

我已多次将我的 C# 代码与此事件挂钩,但奇怪的是,我的测试部门和其他几个人注意到,尽管 VB6 引发了此事件的 aBadPIN 设置为 false,c# 事件处理程序将其接收为 true。它不一致,所以这是“那些”问题之一,但我在互联网上找不到任何有帮助的东西。

我发现,如果我定义一个新事件,将 bool 转换为字节并发送该事件,然后将其转换回 c# 中,这将解决这些问题机器上的问题。然而,我真的不想这样做,因为我必须对在我的 COM 和 .Net 库(而且有很多库)之间编组的每个 bool 都这样做。

我还在某处读到,有一个已知的错误(至少在 C++ 中),您必须将 EAX 寄存器强制为 255 才能正确表示 false,但我以前从未遇到过这个问题,坦率地说,我不知道从哪里开始这样做无论如何,VB6。

任何想法都会很棒!

更新:日志记录显示,当发生此问题时,引发事件的调用会在 c# 事件处理程序触发之前将控制权返回给 VB6 代码。这是怎么回事?

更新:在引发代码退出后仍然看到事件处理程序接收事件,但尝试封送更改无济于事。时间限制将迫使我遗憾地添加一个包装器。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾`听者〃 2025-01-04 15:31:16

抱歉,这个问题并不像 VB6 世界中的按位布尔运算那么简单。

如果问题出在编组上,.NET 生成的互操作 DLL 是否可能与其各自的 VB6 DLL 不同步? (顺便说一句,您熟悉 VB6 中的二进制兼容性设置吗?)

为了搞笑,我做了以下操作 - 请让我知道这组简单的项目是否是您正在跟踪的编码或编组问题的代表性模型。如果此问题是编组问题,则通过 c# 和 vb6 项目的简化版本来解决该问题可能会有所帮助。

使用 VB6,我创建了一个简单的 ActiveX DLL(名为 LibBoolBuster 的项目),其中包含一个名为 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

使用 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 )等)

非常简单的项目:单击一个按钮,调用 DoIt,触发事件 WriteComplete。我尝试了一下,一切都按预期进行。


仔细看看VB6这边。您指示该事件是通过以下方式引发的:

RaiseEvent WriteComplete(aCommsReceived, Not (aIsAcknowledged))

确保 aIsAcknowledged 仅是 0 或 -1;否则你将不会得到你期望的结果。

VB6布尔运算符都是按位的;即 (Not 1) 导致 -2 非零。

此外,在 VB6 中,当从整数转换为布尔值时,任何非零整数都将映射为 True - 只有零变为 false。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文