gaerelva 2024-07-30 10:13 采纳率: 90.9%
浏览 3
已结题

c++ extern c 实现代码如何写

c++代码 打包 dll 给 c#使用
这几个方法如何实现
尤其带参数double(*f)(double)的,如何在exter c里面定义和实现,
以及在c#段调用dll的引用代码,和使用代码
我的c++的代码如下,调用的c++代码也有,请仿写c#的
要完整代码,谢谢

#include <cmath>
#include <iostream>
#include "Complex.h"
#include "MatrixVector.h"
#include "AlgebraLinear.h"
#include "RND.h"
using namespace std;

extern "C" {
    __declspec(dllexport) void* NonLinearEquation_create() ;

//写的不对
    //__declspec(dllexport) int NonLinearEquation_dhrt(void* ptr,double a, double b, double h, double eps, double* x,int m, double (*f)(double));

//c#中引用 下面写法错误
 //[DllImport("my.dll", CallingConvention = CallingConvention.Cdecl)]
 // public static extern int NonLinearEquation_dhrt(IntPtr ptr,double a, double b, double h, double eps, double* x,int m, double (*f)(double));
        

}
class NonLinearEquation
{
public:
    NonLinearEquation(void);
    ~NonLinearEquation(void);

    /////////////////////////////////////////////
    //用对分发搜索方程f(x)=0 在区间[a,b]内的实根
    //方程求根对分法
    //a        求根区间的左端点。
    //b        求根区间的右端点。
    //h        搜索求根所采用的步长。
    //eps      控制精度要求。
    //x[m]     存放返回的实根。实根个数由函数值返回。
    //m        实根个数的预估值。
    //f        方程左端函数f(x)的函数名。
    //函数返回搜索到的实根个数。若此值等于m,则有可能没有搜索完。
    /////////////////////////////////////////////
    int dhrt(double a, double b, double h, double eps, double x[], 
        int m, double (*f)(double))
    { 
        int n,js;
        double z,y,z1,y1,z0,y0;
        if (a>b)
        {
            z = a;
            a = b; 
            b = z;
        }
        n=0; 
        z=a; 
        y=(*f)(z);
        while ((z<=b+h/2.0)&&(n!=m))
        { 
            if (fabs(y)<eps)
            { 
                n=n+1; 
                x[n-1]=z;
                z=z+h/2.0; 
                y=(*f)(z);
            }
            else
            { 
                z1=z+h; y1=(*f)(z1);
                if (fabs(y1)<eps)
                { 
                    n=n+1;
                    x[n-1]=z1;
                    z=z1+h/2.0; 
                    y=(*f)(z);
                }
                else if (y*y1>0.0)
                { 
                    y=y1; z=z1;
                }
                else
                { 
                    js=0;
                    while (js==0)
                    { 
                        if (fabs(z1-z)<eps)
                        { 
                            n=n+1; 
                            x[n-1]=(z1+z)/2.0;
                            z=z1+h/2.0; 
                            y=(*f)(z);
                            js=1;
                        }
                        else
                        { 
                            z0=(z1+z)/2.0; y0=(*f)(z0);
                            if (fabs(y0)<eps)
                            { 
                                x[n]=z0; n=n+1; js=1;
                                z=z0+h/2.0; y=(*f)(z);
                            }
                            else if ((y*y0)<0.0)
                            { 
                                z1=z0; y1=y0;
                            }
                            else { z=z0; y=y0;}
                        }
                    }
                }
            }
        }
        return(n);
    }
    
        int snse(int n,double eps,double x[],double (*f)(double [],double [],int))
    {
        int i,k,flag,interation;
        double y,*yy,d,s;
        interation = 1000;          //最大迭代次数
        yy=new double[n];
        k=0;  flag=0;
        while ((k<interation)&&(flag==0))
        {
            y = (*f)(x,yy,n);          //计算目标函数值F以及目标函数的n个偏导数
            if (y<eps)  flag = 1;
            else
            {
                k = k + 1;
                d=0.0;
                for (i=0; i<=n-1; i++) d=d+yy[i]*yy[i];   //计算D
                if (d+1.0==1.0) 
                {  
                    delete[] yy;   return(-1);
                }
                s=y/d;
                for (i=0; i<=n-1; i++) 
                    x[i]=x[i]-s*yy[i];              //计算新的校正值X
            }
        }
        delete[] yy; 
        return(k);
    }
    

    
    };
    


        
        // C++调用例子1
    //方程求根对分法例
    #include <cmath>
    #include <iostream>
    using namespace std;
    int main()
    { 
    int i,n;
    int m=6;
    double x[6];
    double dhrtf(double);
    n=dhrt(-2.0,5.0,0.2,0.000001,x,m,dhrtf);
    cout <<"根的个数 = " <<n <<endl;
    for (i=0; i<=n-1; i++)
    cout <<"x(" <<i <<") = " <<x[i] <<endl;
    return 0;
    }
    //f(x)
    double dhrtf(double x)
    { 
    double z;
    z=(((((x-5.0)*x+3.0)*x+1.0)*x-7.0)*x+7.0)*x-20.0;
    return(z);
    }
    
// C++调用例子2
    //非线性方程组梯度法例
    #include <cmath>
    #include <iostream>
    using namespace std;
    int main()
    { 
    int i,k;
    double eps, snsef(double [], double [], int);
    double x[3]={1.5,6.5,-5.0};
    eps=0.000001;
    k = snse(3,eps,x,snsef);
    cout <<"迭代次数 = " <<k <<endl;
    for (i=0; i<=2; i++)
    cout <<"x(" <<i <<")=" <<x[i] <<endl;
    return 0;
    }

    double snsef(double x[],double y[],int n)
    { double z,f1,f2,f3,df1,df2,df3;
    n=n;
    f1=x[0]-5.0*x[1]*x[1]+7.0*x[2]*x[2]+12.0;
    f2=3.0*x[0]*x[1]+x[0]*x[2]-11.0*x[0];
    f3=2.0*x[1]*x[2]+40.0*x[0];
    z=f1*f1+f2*f2+f3*f3;
    df1=1.0; df2=3.0*x[1]+x[2]-11.0; df3=40.0;
    y[0]=2.0*(f1*df1+f2*df2+f3*df3);
    df1=-10.0*x[1]; df2=3.0*x[0]; df3=2.0*x[2];
    y[1]=2.0*(f1*df1+f2*df2+f3*df3);
    df1=14.0*x[2]; df2=x[0]; df3=2.0*x[1];
    y[2]=2.0*(f1*df1+f2*df2+f3*df3);
    return(z);
    }
 
    
  • 写回答

1条回答 默认 最新

  • GISer Liu 2024-07-30 11:06
    关注

    该回答引用自GPT-3.5, 由博主 GISer Liu 编写:

    为了实现C++代码打包成DLL并在C#中使用,特别是处理带参数double (*f)(double)的方法,我们需要在C++和C#中分别进行正确的定义和调用。以下是详细的解决方案:

    1. C++代码修改

    首先,我们需要修正C++代码中的导出函数声明,并确保函数指针参数的正确传递。

    #include <cmath>
    #include <iostream>
    using namespace std;
    
    extern "C" {
        __declspec(dllexport) void* NonLinearEquation_create();
        __declspec(dllexport) int NonLinearEquation_dhrt(void* ptr, double a, double b, double h, double eps, double* x, int m, double (*f)(double));
    }
    
    class NonLinearEquation {
    public:
        NonLinearEquation() {}
        ~NonLinearEquation() {}
    
        int dhrt(double a, double b, double h, double eps, double x[], int m, double (*f)(double)) {
            int n, js;
            double z, y, z1, y1, z0, y0;
            if (a > b) {
                z = a; a = b; b = z;
            }
            n = 0; z = a; y = (*f)(z);
            while ((z <= b + h / 2.0) && (n != m)) {
                if (fabs(y) < eps) {
                    n = n + 1; x[n - 1] = z;
                    z = z + h / 2.0; y = (*f)(z);
                } else {
                    z1 = z + h; y1 = (*f)(z1);
                    if (fabs(y1) < eps) {
                        n = n + 1; x[n - 1] = z1;
                        z = z1 + h / 2.0; y = (*f)(z);
                    } else if (y * y1 > 0.0) {
                        y = y1; z = z1;
                    } else {
                        js = 0;
                        while (js == 0) {
                            if (fabs(z1 - z) < eps) {
                                n = n + 1; x[n - 1] = (z1 + z) / 2.0;
                                z = z1 + h / 2.0; y = (*f)(z);
                                js = 1;
                            } else {
                                z0 = (z1 + z) / 2.0; y0 = (*f)(z0);
                                if (fabs(y0) < eps) {
                                    x[n] = z0; n = n + 1; js = 1;
                                    z = z0 + h / 2.0; y = (*f)(z);
                                } else if ((y * y0) < 0.0) {
                                    z1 = z0; y1 = y0;
                                } else { z = z0; y = y0; }
                            }
                        }
                    }
                }
            }
            return n;
        }
    };
    
    void* NonLinearEquation_create() {
        return new NonLinearEquation();
    }
    
    int NonLinearEquation_dhrt(void* ptr, double a, double b, double h, double eps, double* x, int m, double (*f)(double)) {
        return static_cast<NonLinearEquation*>(ptr)->dhrt(a, b, h, eps, x, m, f);
    }
    

    2. C#代码实现

    在C#中,我们需要使用DllImport来导入C++的DLL,并正确声明函数指针参数。

    using System;
    using System.Runtime.InteropServices;
    
    class Program {
        [DllImport("your_dll_name.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr NonLinearEquation_create();
    
        [DllImport("your_dll_name.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int NonLinearEquation_dhrt(IntPtr ptr, double a, double b, double h, double eps, double[] x, int m, Func<double, double> f);
    
        static double MyFunction(double x) {
            return (((((x - 5.0) * x + 3.0) * x + 1.0) * x - 7.0) * x + 7.0) * x - 20.0;
        }
    
        static void Main() {
            IntPtr ptr = NonLinearEquation_create();
            int m = 6;
            double[] x = new double[m];
            int n = NonLinearEquation_dhrt(ptr, -2.0, 5.0, 0.2, 0.000001, x, m, MyFunction);
            Console.WriteLine("根的个数 = " + n);
            for (int i = 0; i < n; i++) {
                Console.WriteLine("x(" + i + ") = " + x[i]);
            }
        }
    }
    

    3. 解释

    1. C++部分

      • 使用extern "C"__declspec(dllexport)来导出函数。
      • 确保函数指针参数double (*f)(double)正确传递。
    2. C#部分

      • 使用DllImport来导入C++的DLL。
      • 使用Func<double, double>来声明函数指针参数。
      • Main函数中调用C++的函数并处理返回结果。

    通过以上步骤,您可以在C#中正确调用C++的DLL,并处理带函数指针参数的方法。

    如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 8月7日
  • 已采纳回答 7月30日
  • 创建了问题 7月30日

悬赏问题

  • ¥20 校园二手交易小程序搭建
  • ¥15 请问在ubuntu用conda创建环境报错怎么能解决
  • ¥15 STM32CubeMX/proteus按键控制指示灯颜色切换
  • ¥20 python,计算区位熵和扩张指数
  • ¥15 Python环境配置
  • ¥15 大四学生的困惑,有偿提问!
  • ¥15 解决页面无法编入索引:被“noindex”标签排除的问题?
  • ¥15 arduino测量电阻
  • ¥15 快手uid转快手号谁能解决 需要开发
  • ¥15 iis部署Django时css不生效,来个真人,ai不好使