【问题标题】:minpack fortran .dll for use in c#用于 c# 的 minpack fortran .dll
【发布时间】:2013-09-11 11:04:17
【问题描述】:

我正在尝试在我的 c# windows 窗体解决方案中包含 minpack,它是用 FORTRAN 编写的,用于解决未定数学问题的最小二乘解决方案。

我已经读到可以将 minpack fortran 子例程编译成 .dll,其中有 7 个(都在单独的文件中),然后我可以将其添加为 Visual Studio 2012 中我的 c# 程序的引用。

我已经尝试了 2 天,但运气不佳。我已经下载了 GCC GNU 来编译 fortran 文件。到目前为止,我的步骤是:

1) 使用 mingw64env 命令提示符中的语法“gcc -c filename1.f”为所有 7 个文件将 fortran 文件编译为通用对象文件格式 (COFF *.o) 文件

2) 然后我使用语法“gcc -shared -o mindpack.dll filename1.o filename2.o filename3.o...”将这些文件一起编译成一个共享的可执行文件

这会输出一个没有报告错误的 .dll 文件。

3) 但是当我尝试将其添加为对我的 windows 窗体项目 (c#) 的引用时,我收到错误消息“无法添加对 '*.dll' 的引用。请确保该文件是可访问的,并且它是一个有效的程序集或 COM 组件。”

4) 解决此问题的建议之一是找到文件 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\TlbImp.exe 并使用语法“TlbImp.exe”执行它minpack.dll”,但这会给出错误“TlbImp:错误 T10000:输入文件 'C:\mingw64\minpack.dll' 不是有效的类型库。

谁能指出我正确的方向,因为我才刚刚开始学习 c#,并且一些在线解决方案对于头文件和 DEF 文件之类的东西让我头疼,我不确定这些是否相关。

如果有人能提出一个解决方案,将一组 fortran 子例程转换为一个可以从 c# 调用的单个 .dll 文件,最好使用 GCC GNU(或其他一些免费软件),将不胜感激。

提前致谢。

【问题讨论】:

    标签: c# gcc dll fortran gnu


    【解决方案1】:

    无法将非托管 dll 添加为对 C# 应用程序的引用。 GCC 无法为您轻松链接 COM 对象。

    如果 dll 导出多个全局函数,那么您应该可以使用 Platfrom Invoke(DllImport 属性)从 C# 调用它们

    请查看此 article 或 Google 搜索中的任何其他内容。

    【讨论】:

    • 只有一个全局函数,其余的只能在全局函数中调用。这会完全改变您的建议吗?还是继续这样做?
    • 一个全局函数或它们的数量没有区别。这只意味着,你必须通过 P/Invoke 调用单个函数,从而简化事情。
    【解决方案2】:

    这个答案与问题有些正交,因为它完全避免了 Fortran,但鉴于 C# 和 MINPACK 搜索结果中问题的普遍性,值得一提的是open source C/C++ port of MINPACK 可用,这可能会简化使某些东西可以从 .NET 中调用。

    要使用这个特定的库,

    1. 下载release version of the source code,在撰写本文时最新版本为 1.6.3。
    2. 打开其中包含的 Visual C++ 解决方案 cminpack.sln,并构建它以获得库 cminpack_dll.dll
    3. cminpack_dll.dll 添加到您的 .NET 解决方案中,并确保在构建时将其复制到输出目录。
    4. 此时可以使用P/Invoke调用库。

    以下示例显示了如何将二次函数拟合到给定的数据点集合:

    class Program
    {
        static void Main()
        {
            // Define some test data by 5i + 3i^2. The plan is to let cminpack figure out
            // the values 5 and 3.
            var data = Enumerable.Range(0, 20)
                .Select(i => 5 * i + 3 * Math.Pow(i, 2))
                .ToList();
    
            CminpackFuncMn residuals = (p, m, n, x, fvec, iflag) =>
            {
                unsafe
                {
                    // Update fvec with the values of the residuals x[0]*i + x[1]*i^2 - data[i].
                    var fvecPtr = (double*)fvec;
                    var xPtr = (double*)x;
                    for (var i = 0; i < m; i++)
                        *(fvecPtr + i) = *xPtr * i + *(xPtr + 1) * Math.Pow(i, 2) - data[i];
                }
                return 0;
            };
    
            // Define an initial (bad) guess for the value of the parameters x.
            double[] parameters = { 2d, 2d };
            var numParameters = parameters.Length;
            var numResiduals = data.Count;
            var lwa = numResiduals * numParameters + 5 * numParameters + numResiduals;
    
            // Call cminpack
            var info = lmdif1(
                fcn: residuals,
                p: IntPtr.Zero,
                m: numResiduals,
                n: numParameters,
                x: parameters,
                fvec: new double[numResiduals],
                tol: 0.00001,
                iwa: new int[numParameters],
                wa: new double[lwa],
                lwa: lwa);
    
            // parameters now contains { 5, 3 }.
            Console.WriteLine($"Return value: {info}, x: {string.Join(", ", parameters)}");
        }
    
        [DllImport("cminpack_dll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int lmdif1(CminpackFuncMn fcn, IntPtr p, int m, int n, double[] x,
            double[] fvec, double tol, int[] iwa, double[] wa, int lwa);
    
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int CminpackFuncMn(IntPtr p, int m, int n, IntPtr x, IntPtr fvec, int iflag);
    }
    

    这里,lmdif1CminpackFuncMn的签名可以通过查看cminpack中的relevant header file来推断。

    【讨论】:

      猜你喜欢
      • 2019-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多