将 Visual Basic 6.0 类型转换为 VB.NET 'Structure'
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13354517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert Visual Basic 6.0 type to VB.NET 'Structure'
提问by Dan Barron
EDIT: Having gotten this to work under 32-bit, I'm now trying to get it to work for 64-bit. I've gotten source code for the DLL and both DLL and application are being compiled for 64-bit. I get an access violation every time. Here is the DLL code (C++ in Visual Studio 2005):
编辑:让它在 32 位下工作后,我现在试图让它在 64 位下工作。我已经获得了 DLL 的源代码,并且正在为 64 位编译 DLL 和应用程序。我每次都会遇到访问冲突。这是 DLL 代码(Visual Studio 2005 中的C++ ):
#pragma pack( push, 2 )
// Output Results Structure
typedef struct tagTVA_RESULTS {
int iID; /* Difference ID 1 .. n */
int iLeft; /* Bounding rectangle */
int iRight;
int iTop;
int iBottom;
double dCx; /* Center of gravity */
double dCy;
double dMajor; /* Shape information */
double dMinor;
double dAngle; /* Rotational information */
int lArea; /* Number of pixels */
int iEdge; /* Set if difference is at the edge of the image */
double dNormalDensity;
int iNormalCount;
double dDifferenceDensity;
} TVA_RESULTS, *PTVA_RESULTS;
#pragma pack ( pop )
Note it's setting the pack to 2. I've tried setting it to 2 in the application as well, and it fails. I tried other values, and I even tried values that weren't the same. I've tried explicit using 4 as integer size and 8 as double size. But I would assume (with limited knowledge) that if both pack sizes are the same, it should work.
请注意,它将包设置为 2。我也尝试在应用程序中将其设置为 2,但失败了。我尝试了其他值,甚至尝试了不同的值。我已经尝试明确使用 4 作为整数大小和 8 作为双倍大小。但我会假设(知识有限)如果两个包装尺寸相同,它应该可以工作。
At this point I'm suspecting how the function is called. Its first parameter is a pointer to an array of these structures. The application passes in the first element of the array ByRef, which I think accomplishes this. But having a bad pointer to the array would explain the symptoms. Here's the function definition in the DLL.
在这一点上,我怀疑该函数是如何调用的。它的第一个参数是一个指向这些结构数组的指针。应用程序传入数组 ByRef 的第一个元素,我认为它实现了这一点。但是有一个错误的数组指针可以解释这些症状。这是 DLL 中的函数定义。
int WINAPI MNtvaAnalyzeVB (TVA_RESULTS *pResults, int iMaxCount)
My boss suggested it could be an big/little endianproblem, but that seems unlikely if they're both being compiled in the same environment.
我的老板建议这可能是一个大/小端问题,但如果它们都在同一环境中编译,这似乎不太可能。
What should I do?
我该怎么办?
End of edit >>>
编辑结束>>>
I am converting a Visual Basic 6.0 application to VB.NET. I have a couple of structures that get passed to external DLL files. This is not working, and I have a feeling it's due to the structures not being passed correctly.
我正在将 Visual Basic 6.0 应用程序转换为 VB.NET。我有几个结构可以传递给外部 DLL 文件。这是行不通的,我有一种感觉,这是由于结构没有被正确传递。
Here's the original structure:
这是原始结构:
Public Type TVA_PARAMETERS
iStandardFilterOnOff As Long
iSampleFilterOnOff As Long
iDifferenceFilterOnOff As Long
iRotationCorrectionOnOff As Long
iLocalCorrectionOnOff As Long
iStandardAOIx As Long
iStandardAOIy As Long
iStandardAOIdx As Long
iStandardAOIdy As Long
iSampleAOIx As Long
iSampleAOIy As Long
iSampleAOIdx As Long
iSampleAOIdy As Long
iRepeatHorizontal As Long
iRepeatVertical As Long
dSensitivity As Double
iMergeWidth As Long
iMergeHeight As Long
iMinimumDifferenceArea As Long
iMaximumDifferenceArea As Long
End Type
If I do a LenB on a variable of that type in Visual Basic 6.0, I get 84 bytes. (N.B.: I'm not sure if that's a valid way to determine its size.)
如果我在 Visual Basic 6.0 中对该类型的变量执行 LenB,我得到 84 个字节。(注意:我不确定这是否是确定其大小的有效方法。)
I have tried to convert it to VB.NET thusly:
我试图将其转换为 VB.NET:
Public Structure TVA_PARAMETERS
Public iStandardFilterOnOff As Integer
Public iSampleFilterOnOff As Integer
Public iDifferenceFilterOnOff As Integer
Public iRotationCorrectionOnOff As Integer
Public iLocalCorrectionOnOff As Integer
Public iStandardAOIx As Integer
Public iStandardAOIy As Integer
Public iStandardAOIdx As Integer
Public iStandardAOIdy As Integer
Public iSampleAOIx As Integer
Public iSampleAOIy As Integer
Public iSampleAOIdx As Integer
Public iSampleAOIdy As Integer
Public iRepeatHorizontal As Integer
Public iRepeatVertical As Integer
Public dSensitivity As Double
Public iMergeWidth As Integer
Public iMergeHeight As Integer
Public iMinimumDifferenceArea As Integer
Public iMaximumDifferenceArea As Integer
End Structure
In VB.NET, System.Runtime.InteropServices.Marshal.sizeof()gives 88 bytes. I was hoping since these are just numeric values this would work (I know strings can be a pain). I don't have code for the external function, but it's declared like this:
在 VB.NET 中,System.Runtime.InteropServices.Marshal.sizeof()提供 88 个字节。我希望因为这些只是数字值,所以这会起作用(我知道字符串可能很痛苦)。我没有外部函数的代码,但它是这样声明的:
Declare Function MNtvaParameters Lib "MNTva.dll" (ByRef pParameters As TVA_PARAMETERS) As Integer
I'm guessing this structure is not the same size, so the DLL file call fails, but I get no error, and as I said, I don't have the code to look it. It returns a zero, as is should if it's successful, but it's clearly not actually having an effect.
我猜这个结构的大小不一样,所以 DLL 文件调用失败,但我没有收到错误,正如我所说,我没有代码来查看它。它返回一个零,如果它成功就应该如此,但它显然实际上没有效果。
I've played around a bit with Runtime.InteropServices.StructLayoutAttribute, but if that's the answer, I cannot determine the right parameters.
我玩过Runtime.InteropServices.StructLayoutAttribute,但如果这是答案,我无法确定正确的参数。
I have another structure like this, but it's so similar. I'm guessing if I can fix this one, I'll be able to fix the other.
我有另一个这样的结构,但它是如此相似。我猜如果我能解决这个问题,我就能解决另一个问题。
采纳答案by Dan Barron
Well of course the very next thing I tried fixed the problem. Defining the structure like this:
嗯,当然,接下来我尝试解决了这个问题。像这样定义结构:
<Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential, Pack:=1)> _
Public Structure TVA_PARAMETERS
Public iStandardFilterOnOff As Integer
...
etc.
fixed the problem.
解决了这个问题。
回答by Paul Ishak
Here are good resources:
这里有很好的资源:
- Visual Basic 6.0: Data Types
- VB.NET 2012: Data Type Summary (Visual Basic)
- Visual Basic 6.0:数据类型
- VB.NET 2012:数据类型摘要 (Visual Basic)
Your conversion looks good, a longin Visual Basic 6.0 is 4 bytes which is 32 bits which is an integer in VB.NET. Doubles are 8 bytes both in VB.NET and Visual Basic 6.0 (according to the above articles). I also get 84 bytes in VB.NET.
您的转换看起来不错,longVisual Basic 6.0 中的 a 是 4 个字节,即 32 位,这是 VB.NET 中的整数。双打在 VB.NET 和 Visual Basic 6.0 中都是 8 个字节(根据上述文章)。我也在 VB.NET 中得到 84 个字节。
Option Strict On
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim A As New TVA_PARAMETERS
MsgBox(A.ByteCount.ToString)
End Sub
Public Structure TVA_PARAMETERS
Public iStandardFilterOnOff As Int32
Public iSampleFilterOnOff As Int32
Public iDifferenceFilterOnOff As Int32
Public iRotationCorrectionOnOff As Int32
Public iLocalCorrectionOnOff As Int32
Public iStandardAOIx As Int32
Public iStandardAOIy As Int32
Public iStandardAOIdx As Int32
Public iStandardAOIdy As Int32
Public iSampleAOIx As Int32
Public iSampleAOIy As Int32
Public iSampleAOIdx As Int32
Public iSampleAOIdy As Int32
Public iRepeatHorizontal As Int32
Public iRepeatVertical As Int32
Public dSensitivity As Double
Public iMergeWidth As Int32
Public iMergeHeight As Int32
Public iMinimumDifferenceArea As Int32
Public iMaximumDifferenceArea As Int32
Function ByteCount() As Integer
Dim Results As New List(Of Byte)
AddBytesToList(Results, BitConverter.GetBytes(iStandardFilterOnOff))
AddBytesToList(Results, BitConverter.GetBytes(iSampleFilterOnOff))
AddBytesToList(Results, BitConverter.GetBytes(iDifferenceFilterOnOff))
AddBytesToList(Results, BitConverter.GetBytes(iRotationCorrectionOnOff))
AddBytesToList(Results, BitConverter.GetBytes(iLocalCorrectionOnOff))
AddBytesToList(Results, BitConverter.GetBytes(iStandardAOIx))
AddBytesToList(Results, BitConverter.GetBytes(iStandardAOIy))
AddBytesToList(Results, BitConverter.GetBytes(iStandardAOIdx))
AddBytesToList(Results, BitConverter.GetBytes(iStandardAOIdy))
AddBytesToList(Results, BitConverter.GetBytes(iSampleAOIx))
AddBytesToList(Results, BitConverter.GetBytes(iSampleAOIy))
AddBytesToList(Results, BitConverter.GetBytes(iSampleAOIdx))
AddBytesToList(Results, BitConverter.GetBytes(iSampleAOIdy))
AddBytesToList(Results, BitConverter.GetBytes(iRepeatHorizontal))
AddBytesToList(Results, BitConverter.GetBytes(iRepeatVertical))
AddBytesToList(Results, BitConverter.GetBytes(dSensitivity))
AddBytesToList(Results, BitConverter.GetBytes(iMergeWidth))
AddBytesToList(Results, BitConverter.GetBytes(iMergeHeight))
AddBytesToList(Results, BitConverter.GetBytes(iMinimumDifferenceArea))
AddBytesToList(Results, BitConverter.GetBytes(iMaximumDifferenceArea))
Return Results.Count
End Function
Sub AddBytesToList(ByRef List As List(Of Byte), addBytes As Byte())
For Each B As Byte In addBytes
List.Add(B)
Next
End Sub
End Structure
End Class

