![]() |
1
1
Caveat: 在我开始之前,人们可能有兴趣从你的其他问题中注意到一些问题。 REF: How do I send/receive windows messages from VB6 and C#? 正如这里和你的另一篇文章所提到的,你真的应该重新考虑如何使这项工作发挥作用。尤其是,即使您对这里的技术很好,您的同事或其他可能需要维护您的代码的人也会遇到非常糟糕的情况。注意调试过程在vb6中也非常困难-经常保存并使用很多断点!如果代码中存在错误,则会出现大量崩溃。 此外,不应将邮件与此技术一起使用。这需要更多的清理工作。 解决方案: 我附带了一个示例,它可以返回只包含字符串和整数类型的结构。这项工作需要大量的运动部件。我们将深入讨论从C到VB的过程,因为这更为棘手。一旦你知道如何做到这一点,反过来就不难了。 首先,在C面,您应该声明您的结构。结构的包装在C中实际上并不坏。下面是一个C示例类,它是COM可见的,演示了如何包装结构。关键是在您的呼叫的对方使用marshal.structureToptr和marshal.destroystructure。根据所涉及的类型,您甚至不必编写代码来映射类型。使用marshalas属性为vb6标记正确的映射。marshalas中使用的枚举中的大多数项对应于variants和com自动化中使用的不同变量类型。 这里使用的缓冲区由hglobal支持,调用结束后需要释放该缓冲区。这里也可以使用gchandle,这也需要类似的清理。 MarshalAsAttribute Class @ MSDN
Marshal.StructureToPtr Method @ MSDN
在vb6端,您需要设置一个机制来拦截消息。由于细节在您的其他问题和其他地方都有介绍,我将跳过子类化的主题。 要在vb6端解包结构,需要对每个字段执行此操作,因为没有现成的机制可以取消对指针值的引用并将其转换为结构。幸运的是,如果您没有在C中另外指定字段成员,您可以期望字段成员在VB6的4字节边界上对齐。这允许我们逐个字段地工作,将项目从一个表示映射到另一个表示。 首先,一些模块代码来完成所有的支持工作。以下是功能和注意事项。
testinfo类型-两边使用的结构的镜像定义。
除了这些项之外,我们还使用了vb6中未记录的varptr()函数来获取项的地址。我们可以用它来索引到vb6端的结构中。有关此功能的详细信息,请参阅以下链接。 How to get the Address of Variables in Visual Basic @ support.microsoft.com
请注意,此解决方案需要发送方和接收方的合作。因为我们不希望两次释放字符串字段,所以在返回控件之前,我们先清空在vb6端所做的复制。如果您试图为字段成员分配一个新值,这里将发生什么是未定义的,因此请避免编辑结构中的字段。
在映射字段中,C中的UnmanagedType.bstr与VB6中的字符串直接类似。
VB6应用程序(表单源代码)的其余部分很简单。
现在,在将结构从vb6发送到c_时,需要执行相反的操作。对于一些简单的结构,您甚至可以只发送结构本身的地址。如果需要memberwise控件,可以使用globalalloc获得合适的缓冲区内存,然后使用globalfree释放它。对于每个字段,memberwise复制的执行方式与参数从C展开的方式相同。但是,调用后清理更简单。如果使用了缓冲区,则只需在将缓冲区中的内存交给globalfree之前将其清零即可。
GlobalAlloc Function (Windows) @ MSDN
当消息到达C端时,使用marshal.ptrtostructure()将intptr映射到.NET结构中。 |
![]() |
2
1
您必须分配guid并使用marshalas属性。.NET COM互操作处理转换。和一个班没什么不同。 This series of posts说明了您需要做什么。 |
![]() |
3
1
通过在.NET上使用p/invoke并在vb6中导入copymemory,您可以做到这一点,但这是一个非常严重的维护灾难,我建议您从类似的任何地方运行。 |
![]() |
cobb208 · Malloc正在为释放指针引发错误 3 年前 |
![]() |
kernel · 打印结构数组内容时出错 3 年前 |
![]() |
mwitz · 在Rust中无法正确写入结构的函数属性 3 年前 |
![]() |
Ulysses · 无法访问结构字段(Rust) 3 年前 |
![]() |
Tor · 使用Box<None>值初始化struct 3 年前 |
![]() |
Yestin · Golang如何初始化数组结构[duplicate] 3 年前 |