导入非托管DLL时,C#和Delphi代码有不同的行为

时间:2015-06-09 11:46:55

标签: c# delphi unmanaged dllexport mathdotnet

我用C#中的Math.Net数字解决稀疏线性方程组。 我试图将此代码导出到dll(使用Robert Giesecke的非托管导出)并从Delphi代码运行它。

这是我的C#代码:

namespace MathNetSolverLib
{
    public class ParticleInterpolator
    {
        public ParticleInterpolator(int eqnumber)
        {
            n = eqnumber;
            b = Vector.Build.DenseOfArray(new double[eqnumber]);
            result = Vector.Build.DenseOfArray(new double[eqnumber]);
            input_points = new List<Tuple<int, int, double>>();
        }

        public void solve()
        {
            using (var writer = new StreamWriter("C:\\users\\s\\desktop\\logb.txt"))
            {
                for (int i = 0; i < n; ++i)
                {
                    writer.WriteLine(b[i]);
                }
            }
            using (var writer = new StreamWriter("C:\\users\\s\\desktop\\loginput.txt"))
            {
                for (int i = 0; i < input_points.Count(); ++i)
                {
                    writer.WriteLine(input_points[i]);
                }
            }

            TFQMR solver = new TFQMR();

            MathNet.Numerics.LinearAlgebra.Solvers.Iterator<double> iter = 
                new MathNet.Numerics.LinearAlgebra.Solvers.Iterator<double>();

            SparseMatrix sd = SparseMatrix.OfIndexed(n, n, input_points);
            solver.Solve(sd, b, result, iter, new DiagonalPreconditioner());



            using (var writer = new StreamWriter("C:\\users\\s\\desktop\\logres.txt"))
            {
                for (int i = 0; i < n; ++i)
                {
                    writer.WriteLine(result[i]);
                }
            }

        }
        public int n;
        public List<Tuple<int, int, double>> input_points;
        public Vector<double> result;
        public Vector<double> b;
    }

    public class Class1
    {
        [DllExport]
        public static ParticleInterpolator create(int eqnumber)
        {           
            return new ParticleInterpolator(eqnumber);
        }

        [DllExport]
        public static void addValue(int row, int col, double value, ParticleInterpolator ins)
        {
            ins.input_points.Add(new Tuple<int, int, double>(row, col, value));
        }

        [DllExport]
        public static void setRhs(int row, double value, ParticleInterpolator ins)
        {
            ins.b[row] = value;
        }

        [DllExport]
        public static void solve(ParticleInterpolator ins)
        {      
            ins.solve();
        }

        [DllExport]
        public static double getSolutionByIndex(int index, ParticleInterpolator ins)
        {
            return ins.result[index];
        }
    }
}

我已将此导入C#dll,如下所示:

 [DllImport("MathNetSolverLib.dll", EntryPoint = "create")]
        public static extern int create(int eqnumber);

        [DllImport("MathNetSolverLib.dll", EntryPoint = "addValue")]
        public static extern void addValue(int row, int col, double value, int ins);

        [DllImport("MathNetSolverLib.dll", EntryPoint = "setRhs")]
        public static extern void setRhs(int row, double value, int ins);

        [DllImport("MathNetSolverLib.dll", EntryPoint = "solve")]
        public static extern void solve(int ins);

        [DllImport("MathNetSolverLib.dll", EntryPoint = "getSolutionByIndex")]
        public static extern double getSolutionByIndex(int index, int ins);

它工作正常。

但是当我尝试在Delphi中导入它时:

function create(n: integer): pointer; stdcall; external MathNetSolverLib;
procedure addValue(row, col: Integer; value:double; p:pointer); stdcall; external MathNetSolverLib;
procedure setRhs(row: Integer; value: double; p:pointer); stdcall; external MathNetSolverLib;
procedure solve(p: pointer); stdcall; external MathNetSolverLib;
function getSolutionByIndex(index: Integer; p:pointer): double; stdcall; external MathNetSolverLib;

TFQMR求解器返回错误的结果。似乎TFQMR内部的算法具有不同的行为。

这很奇怪,因为从C#或Delphi(我已经检查过)调用dll时,所有输入数据(变量A,b,n和input_points)保持不变。

有没有人知道如何解释这个?

0 个答案:

没有答案