#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 )
注意它将包设置为2.我已尝试在应用程序中将其设置为2,但它失败了。我尝试了其他值,我甚至尝试过不同的值。我已经尝试使用4作为整数大小,8作为双倍大小。但我认为(知识有限)如果两种包装尺寸相同,它应该有效。
此时我怀疑该函数是如何调用的。它的第一个参数是指向这些结构数组的指针。应用程序传入数组ByRef的第一个元素,我认为它实现了这一点。但是指向数组的错误指针可以解释症状。这是DLL中的函数定义。
int WINAPI MNtvaAnalyzeVB (TVA_RESULTS *pResults, int iMaxCount)
我的老板认为这可能是一个big/little endian问题,但如果它们都是在同一环境中编译的话,这似乎不太可能。
我该怎么办?
编辑结束>>>
我正在将Visual Basic 6.0应用程序转换为VB.NET。我有几个结构传递给外部DLL文件。这不起作用,我觉得这是由于结构没有正确传递。
这是原始结构:
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
如果我在Visual Basic 6.0中对该类型的变量执行LenB,则得到84个字节。 (N.B。:我不确定这是否是确定其大小的有效方法。)
我试图将其转换为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
在VB.NET中,System.Runtime.InteropServices.Marshal.sizeof()给出了88个字节。我希望,因为这些只是数值,这将起作用(我知道字符串可能会很痛苦)。我没有外部函数的代码,但它的声明如下:
Declare Function MNtvaParameters Lib "MNTva.dll" (ByRef pParameters As TVA_PARAMETERS) As Integer
我猜这个结构大小不一样,所以DLL文件调用失败了,但我没有得到任何错误,正如我所说,我没有代码来查看它。它会返回零,如果它成功的话应该返回它,但它显然实际上没有效果。
我在Runtime.InteropServices.StructLayoutAttribute玩了一下,但如果这就是答案,我无法确定正确的参数。
我有另外这样的结构,但它是如此相似。我猜我是否可以解决这个问题,我将能够解决另一个问题。
答案 0 :(得分:8)
当然,接下来我尝试解决了这个问题。定义这样的结构:
<Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential, Pack:=1)> _
Public Structure TVA_PARAMETERS
Public iStandardFilterOnOff As Integer
...
etc.
修复了问题。
答案 1 :(得分:2)
以下是很好的资源:
您的转换看起来不错,Visual Basic 6.0中的long
是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