我有一个导入 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);
该代码传递了编译器错误,但它有一个运行时错误(FatalExecutionEngineError 异常)。错误是:
运行时遇到致命错误。错误地址位于线程 0x13a0 上的 0x73c36e93。错误代码为 0xc0000005。此错误可能是 CLR 中的错误或用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括 COM 互操作或 PInvoke 的用户封送错误,这可能会损坏堆栈。
我还没有找到 dll 的文档,所以我不能对 dll 说太多,除了它是一个 fortran77 编译代码。它是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
就会抛出 an 。