編集: これを 32 ビットで動作させたので、現在 64 ビットで動作させようとしています。DLL のソース コードを入手し、DLL とアプリケーションの両方を 64 ビット用にコンパイルしています。毎回アクセス違反になります。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 )
パックを 2 に設定していることに注意してください。アプリケーションでも 2 に設定しようとしましたが、失敗します。他の値を試してみましたが、同じではない値も試しました。4 を整数サイズとして、8 を double サイズとして明示的に使用してみました。しかし、私は (限られた知識で) 両方のパックのサイズが同じであれば、うまくいくはずだと思います。
この時点で、関数がどのように呼び出されるのか疑問に思っています。その最初のパラメーターは、これらの構造体の配列へのポインターです。アプリケーションは配列 ByRef の最初の要素を渡します。これにより、これが達成されると思います。しかし、配列への不適切なポインターがあると、症状が説明されます。DLL 内の関数定義は次のとおりです。
int WINAPI MNtvaAnalyzeVB (TVA_RESULTS *pResults, int iMaxCount)
私の上司は、ビッグ/リトルエンディアンの問題である可能性があると示唆しましたが、両方が同じ環境でコンパイルされている場合、それはありそうにありません。
私は何をすべきか?
編集終了 >>>
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 バイトになります。(注:それがそのサイズを決定する有効な方法であるかどうかはわかりません。)
したがって、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で少し遊んでみましたが、それが答えであれば、正しいパラメーターを判断できません。
私はこのような別の構造を持っていますが、それはとても似ています。これを修正できれば、もう一方も修正できると思います。