weixin_42029726 2021-09-07 16:10 采纳率: 0%
浏览 56

C#调用C++DLL的问题

C#调用C++动态链接库的问题
最近想要使用levmar.lib库(C++编写的)中的函数进行曲线拟合,先给出这个库中的函数:

extern int dlevmar_dif(
      void (*func)(double *p, double *hx, int m, int n, void *adata),
      double *p, double *x, int m, int n, int itmax, double *opts,
      double *info, double *work, double *covar, void *adata);

图 1 曲线拟合函数
其中,有个参数为函数!
接下来按照创建C++动态链接库的步骤一步步进行:
(1) 在动态链接库项目中添加头文件声明导出函数

#pragma once
#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif
/*****************包含文件*********************/
#include"levmar.h"
#include"pch.h"

/*****************函数声明*********************/
extern "C" MATHLIBRARY_API double dlevmar_dif_CS(double* p, double* x, int m, int n, int itmax, double opts,
    double* info, double work, double covar, double* adata, int location);


(2) 添加源文件定义导出函数(ros函数不是输出函数,是为了让dlevmar_dif函数使用而编写的)

/*****************包含文件*********************/
#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
#include <utility>//包含标准库文件
#include <limits.h>//包含标准库文件
#include "LMForCSharp.h"//包含用户自定义头文件
#include <stdio.h>//包含标准库文件

/*****************非输出函数函数定义*********************/
void ros(double* p, double* x, int m, int n, void* data)//x代表应力,data代表应变
{
    double* data1;
    data1 = (double*)(data);
    register int i;
    for (i = 0; i < n; i++)
    {
        if (m == 2)
        {
            x[i] = (2 * p[0] / p[1]) * (pow(data1[i], (p[1] - 1)) - pow(data1[i], (-0.5 * p[1] - 1)));
        }
        else if (m == 4)
        {
            x[i] = (2 * p[0] / p[1]) * (pow(data1[i], (p[1] - 1)) - pow(data1[i], (-0.5 * p[1] - 1))) +
                (2 * p[2] / p[3]) * (pow(data1[i], (p[3] - 1)) - pow(data1[i], (-0.5 * p[3] - 1)));
        }
        else if (m == 6)
        {
            x[i] = (2 * p[0] / p[1]) * (pow(data1[i], (p[1] - 1)) - pow(data1[i], (-0.5 * p[1] - 1))) +
                (2 * p[2] / p[3]) * (pow(data1[i], (p[3] - 1)) - pow(data1[i], (-0.5 * p[3] - 1))) +
                (2 * p[4] / p[5]) * (pow(data1[i], (p[5] - 1)) - pow(data1[i], (-0.5 * p[5] - 1)));
        }
    }
}


/*****************输出函数函数定义*********************/
double dlevmar_dif_CS(double* p, double* x, int m, int n, int itmax, double opts,
    double* info, double work, double covar, double* adata, int location)
{
    //使用levmar.lib库中的函数
    int ret = dlevmar_dif(ros, p, x, m, n, itmax, &opts, info, &work, &covar, adata);
    //返回拟合参数
    return p[location];
}



(3)在项目属性中包含“levmar.h”和“levmar.lib、lapack.lib、blas.lib、f2c.lib、tmglib.lib、levmar.lib”,并添加在在附加依赖项中。

img

img

(4)刚才说到levmar库中的函数,有个参数为函数,我是直接在动态链接库项目的源文件中定义的,直接让拟合函数dlevmar_dif来使用,如上面的代码。
(5)所有工作都做好之后,就可以生成DLL了。
(6)接下来说明一下C#调用的情况
首先,把DLL放到启动项目文件夹下就不多说了,直接上代码:

        [DllImport(@"\LMForCSharp.dll", CallingConvention = CallingConvention.Cdecl)]
        //声明动态链接库中的导出函数  
        public static extern double dlevmar_dif_CS(double[] p,
        double[] x, int m, int n, int itmax,  double opts, double[] info,  double work,  double covar, double[] adata, int location);

(7)导入动态链接库也声明导出函数之后,给出使用的代码:

        private void button1_Click(object sender, EventArgs e)
        {
            int m = 2;
            int n = 7;
        int itmax = 10000;
        double work = 0;
        double covar = 0;
        double[] info = new double[10];
        double[] p = new double[m];
        double opts = 0;
        for (int i = 0; i < m; i++)
        {
            p[i] = 0.1;
        }
            /*********************************************应变*********************************************/
            double[] adata = { 1, 1.5, 2, 2.5, 3, 3.5, 4 };
            /*********************************************应力*********************************************/
            double[] x = { 0, 1.1328, 2.2221, 3.4706, 4.9168, 6.5691, 8.4280 };
            /*******************************调用函数*******************************/
            int location = 1;
            double Rp = dlevmar_dif_CS(p, x, m, n, itmax, opts, info,  work,  covar, adata, location);
       }

(8)运行!

img


请求帮助。
写得不清楚的地方我可以在详细说明一下。
之前创建的很多DLL都能够成功使用,但这次由于拟合函数dlevmar_dif有个参数是函数,而且使用了很多指针类型,运行就频频出错,查阅很多资料也无果

  • 写回答

2条回答 默认 最新

  • CSDN专家-link 2021-09-07 16:22
    关注

    看不清楚你怎么给指针变量传值的

    评论

报告相同问题?

问题事件

  • 修改了问题 9月7日
  • 修改了问题 9月7日
  • 修改了问题 9月7日
  • 创建了问题 9月7日

悬赏问题

  • ¥15 有关类的报错,在模块里调用另一个模块的方法下的变量时出错
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格
  • ¥15 kali linux用wget archive.kali.org/archive-key.asc指令下载签名无效(失败)
  • ¥15 openHarmony 利用c++程序在dayu210开发板上实现拉取RTSP视频流并且在屏幕上显示
  • ¥15 GD32H757的can通信配置
  • ¥20 nist随机数测试的问题
  • ¥20 帮我解决这个项目,thank you各位程序员
  • ¥15 哪位能用ea软件做一下,有偿