dll をインポートする vba コードがあります。コードは次のとおりです。
Declare PtrSafe Function g77alscal Lib "g77alscal.dll" _
Alias "g77alscal_" _
(ByRef Nrows As Long, _
ByRef Ncols As Long, _
ByRef Xinput As Single, _
ByRef MDSout As Single, _
ByRef Metric As Single, _
ByRef Sout As Single, _
ByRef Niter As Long, _
ByRef Xdebug As Single, _
ByRef Idebug As Long) As Long
vbaでの呼び出しは
Dim Distance() As Single
Dim MDSout() As Single
Dim Metric(60) As Single
Dim Sout(2) As Single
Dim Niter As Long
Dim Xdebug(5000) As Single
Dim Idebug(30) As Long
Dim ierr As Long
N = CLng(Ncases)
ierr = g77alscal(N, N, Distance(1, 1), MDSout(1, 1), Metric(1), _
Sout(1), Niter, Xdebug(1), Idebug(1))
C#で私は使用しようとしました:
[DllImport("g77alscal.dll",EntryPoint="g77alscal_")]
static extern double g77alscal(ref long nRows,
ref long nCols,
ref double xInput,
ref double mdsOut,
ref double metric,
ref double sOut,
ref long nIter,
ref double xDebug,
ref long iDebug
);
そして、c# 関数の呼び出しは次のとおりです。
long n1 = Distance.Rows.Count;
long n2 = Distance.Columns.Count;
double n3 = double.Parse(Distance.Rows[0].ItemArray[0].ToString());
double n4 = 0;
double n5 = 0;
double n6 = 0;
double n7 = 0;
long n8 = 0;
double result = g77alscal(ref n1, ref n2, ref n3,
ref n4, ref n5, ref n6, ref nIter, ref n7, ref n8);
コードはコンパイラ エラーを渡しましたが、1 つの実行時エラー (FatalExecutionEngineError 例外) がありました。エラーは次のとおりです。
ランタイムで致命的なエラーが発生しました。エラーのアドレスは、スレッド 0x13a0 の 0x73c36e93 でした。エラー コードは 0xc0000005 です。このエラーは、CLR のバグ、またはユーザー コードの安全でない部分または検証不可能な部分のバグである可能性があります。このバグの一般的な原因には、COM 相互運用機能または PInvoke のユーザー マーシャリング エラーが含まれ、スタックが破損する可能性があります。
dll のドキュメントをまだ見つけていないので、fortran77 でコンパイルされたコードであること以外は dll について多くを語ることはできません。spssで使われているalscal関数の実装です。
c# の定義に何か問題がありますか? ヘルプやポインタは非常に役立ちます。
ありがとう。
更新: C# のコードを次のように変更しようとしました。
[DllImport("g77alscal.dll",EntryPoint="g77alscal_")]
static extern int g77alscal(ref int nRows,
ref int nCols,
ref float xInput,
ref float mdsOut,
ref float metric,
ref float sOut,
ref int nIter,
ref float xDebug,
ref int iDebug
);
そして呼び出し:
int n1 = 21;
int n2 = 21;
float n3 = float.Parse(Distance.Rows[0].ItemArray[0].ToString());
float n4 = 0;
float n5 = 0;
float n6 = 0;
float n7 = 0;
int n8 = 0;
int result = g77alscal(ref n1, ref n2, ref n3,
ref n4, ref n5, ref n6, ref nIter, ref n7, ref n8);
さらに、別のパターンを見つけました。コードにブレークポイントを指定してアプリケーションを実行すると、上記のエラー例外がスローされますが、デバッグを行わないと例外がAccessViolationException
スローされます。