• c# 调用c++ dll


    1.c#调用代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    
    namespace Holworth.Utility
    {
        [StructLayout(LayoutKind.Sequential)]
        public class RandomNumberServiceProxy1
        {
            //    //该方式是直接调用C++ DLL内的类的成员函数。  QAEXXZ
            //    [DllImport("RskCPlusPlusEngine.dll", EntryPoint = "?MyOGREHello@MyOGRE1@@QAEXXZ")]
            //    //[DllImport("RskCPlusPlusEngine.dll", EntryPoint = "?MyOGREHello@MyOGRE1@@QAEHH@Z", CharSet = CharSet.Auto)]
            //    public static extern void MyOGREHello();
    
            [DllImport("ModelBank.dll",
             // EntryPoint = "?GenerateInverseRandomNumber@RandomNumberService@@QAEXN@Z",CharSet = CharSet.Auto)]
             EntryPoint = "?GenerateQuasiRandomNumber@RandomNumberService@@UAENHHPAPAN@Z")]
    
            public static extern unsafe double GenerateQuasiRandomNumber(int M, int S, double** res);
    
    
            [DllImport("ModelBank.dll",
                  // EntryPoint = "?GenerateInverseRandomNumber@RandomNumberService@@QAEXN@Z",CharSet = CharSet.Auto)]
                  EntryPoint = "?GenerateInverseRandomNumber@RandomNumberService@@QAENN@Z")]
    
            public static extern double GenerateInverseRandomNumber(double X);
    
    
    
    
    
    
            [DllImport("ModelBank.dll",
                // EntryPoint = "?GenerateInverseRandomNumber@RandomNumberService@@QAEXN@Z",CharSet = CharSet.Auto)]
                EntryPoint = "?test1@RandomNumberService@@QAEXPAPAPAH@Z")]
    
            public static extern double test1(IntPtr[] res);
    
        }
    
        public  class RandomNumberService
        {
         
            public  double GenerateQuasiRandomNumber(int M, int S, double[][] R)
            {
    
              
                unsafe
                {
                   
                    IntPtr handle = System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double))*R.Length);// stackalloc double*[R.Length];
                    double** buffer = (double**)handle;
                    //double** buffer = stackalloc double*[R.Length];
                    for (int i = 0; i < R.Length; i++)
                    {
                        //从 COM 任务内存分配器分配指定大小的内存块。
                        //buffer[i] = Marshal.AllocHGlobal(Marshal.SizeOf(R[0][0]) * R[i].Length);
                        ////将数据从一维的托管 32 位有符号整数数组复制到非托管内存指针。
                        //Marshal.Copy(R[i], 0, buffer[i], R[i].Length);
                        var s1 = stackalloc double[R[i].Length];
                        buffer[i] = s1;
                        for (int j = 0; j < R[i].Length; j++)
                        {
                            buffer[i][j] = R[i][j];
    
                        }
                    }
    
                   var d= RandomNumberServiceProxy1.GenerateQuasiRandomNumber(M, S, buffer);
                    Console.WriteLine("d===="+d);
                    System.Runtime.InteropServices.Marshal.FreeHGlobal(handle);
                }
                //for (int i = 0; i < R.Length; i++)
                //{
                //    Marshal.Copy(buffer[i], R[i], 0, R[i].Length);
                //   // Marshal.FreeCoTaskMem(buffer[i]);
                //}
                return 0;
    
            }
    
    
    
            public  double GenerateInverseRandomNumber(double X)
            {
                return RandomNumberServiceProxy1.GenerateInverseRandomNumber(X);
            }
    
            public  double test1(int[][][] array3)
            {
    
                //创建用于封送的表示指针的数组,数组中的每个指针对应三维数组中的一个二维数组
                IntPtr[] intPtrSet2 = new IntPtr[array3.Length];
    
                //封装三维数组
                for (int i = 0; i < array3.Length; i++)
                {
                    //创建用于封装的表示指针的数组,数组中的每个指针对应二维数组中的一个一维数组
                    IntPtr[] intPtrSet1 = new IntPtr[array3[i].Length];
                    //记录二维数组中数据的总个数
                    int length = 0;
                    for (int j = 0; j < array3[i].Length; j++)
                    {
                        //分配相应大小的内存空间
                        intPtrSet1[j] = Marshal.AllocCoTaskMem(Marshal.SizeOf(array3[0][0][0]) * array3[i][j].Length);
                        length += array3[i][j].Length;
                        //将数据从一维的托管 数组复制到非托管内存指针
                        Marshal.Copy(array3[i][j], 0, intPtrSet1[j], array3[i][j].Length);
                    }
                    //分配相应大小的内存空间
                    intPtrSet2[i] = Marshal.AllocCoTaskMem(Marshal.SizeOf(array3[0][0][0]) * length);
                    //将数据从一维托管 IntPtr 数组复制到非托管内存指针
                    Marshal.Copy(intPtrSet1, 0, intPtrSet2[i], array3[i].Length);
    
                    ////释放一维托管 IntPtr 数组
                    //for (int j = 0; j < array3[i].Length; j++)
                    //{
                    //    Marshal.FreeCoTaskMem(intPtrSet1[j]);
                    //}
                }
    
                RandomNumberServiceProxy1.test1(intPtrSet2);
    
                //////将数据从非托管指针还原在托管三维嵌套数组中
                //for (int i = 0; i < array3.Length; i++)
                //{
                //    //创建一维托管 IntPtr 数组
                //    IntPtr[] intPtrSet1 = new IntPtr[array3[i].Length];
                //    //将数据从非托管内存指针复制到托管 IntPtr 数组
                //    Marshal.Copy(intPtrSet2[i], intPtrSet1, 0, array3[i].Length);
                //    //释放非托管指针
                //    Marshal.FreeCoTaskMem(intPtrSet2[i]);
                //    //将数据存储在三维嵌套数组中
                //    for (int j = 0; j < array3[i].Length; j++)
                //    {
                //        Marshal.Copy(intPtrSet1[j], array3[i][j], 0, array3[i][j].Length);
                //        //Marshal.FreeCoTaskMem(intPtrSet1[j]);
                //    }
    
    
                //}
    
                return 0;
    
            }
    
    
    
    
        }
    }
    
    2.c++代码
    IRandomNumberService.h
    #pragma once
    #define DLL_CLASS __declspec(dllexport)
    #include <array>
    #include <vector>
    DLL_CLASS class IRandomNumberService
    {
    public:
        virtual double  GenerateQuasiRandomNumber(int M, int S,  double** R)=0;
    
        virtual double GenerateInverseRandomNumber(double X)=0;
    };
    
    
    RandomNumberService.h
    //1.类的函数的内联实现
    using namespace std;
    #include "IRandomNumberService.h"
    #define _USE_MATH_DEFINES
    #ifndef ModelBankDll_H_
    #define ModelBankDll_H_
    #pragma once
    #define DLL_EXPORTS
    #ifdef DLL_EXPORTS
    //#define DLL_API extern "C" __declspec(dllexport)
    #define DLL_CLASS __declspec(dllexport)
    #else
    /*#define DLL_API extern "C" __declspec(dllimport) */
    #define DLL_CLASS __declspec(dllimport)
    #endif
    
    
    
    class DLL_CLASS  RandomNumberService :IRandomNumberService
    {
    public:
        RandomNumberService()
        {
    
        }
        // 通过 IRandomNumberService 继承
         double  GenerateQuasiRandomNumber(int M, int S, double** R) ;
         double GenerateInverseRandomNumber(double X ) ;
         double round(double f, int precious);
         void test1(int ***r);
    
    };
    #endif
    RandomNumberService.cpp
    
    #include "stdafx.h"
    #include "RandomNumberService.h"
    #include <math.h>
    #include<iomanip>
    #include <iostream>
    using namespace std;
    //namespace Holworth_Services_Risk
    //{
    
        double RandomNumberService::round(double f, int precious)
        {
            double d = f - (int)f;//取小数部分。
            d *= pow(10, precious);//小数点左移。
            if (d - (int)d >= 0.5) d += 1; //四舍五入
            d = (int)d; //取整数部分。
            d /= pow(10, precious);//小数点右移。
            d += (int)f;//加上原本的整数部分。
            return d;
        }
        void RandomNumberService::test1(int ***R) 
        {
            cout << "r[0][0][0]=" << R[0][0][0] << endl;
        
        }
        // 通过 IRandomNumberService 继承
       double  RandomNumberService::GenerateQuasiRandomNumber(int M, int S, double **R)
        {
            char *c = new char[10];
            delete[] c;
            cout << "r[0][0]======" << R[0][0] << endl;
            bool primeVal;
            bool flagVal;
            double startNum;
            double nextNum;
            double divNum;
            double A, Q, X, Y, Z;
            double B = 0.0;
            int M1 = 0;
            int M2 = 0;
            int L = 0;
    
            int coeffNum[100][100] = { 0 };
    
            double E[1000] = { 0.0 };
    
            //S = 2;
            //M = SetNum;
            //obtain the base prime number which is greater than the number of time steps
    
            if (S <= 2)
                B = 2;
            else if (S == 3)
                B = 3;
            else
            {
                for (int i = S; i <= 100000; i++)
                {
                    primeVal = true;
                    flagVal = false;
    
                    L = i / 2;
    
                    for (int j = 2; j <= L; j++)
                    {
                        if (i % j == 0)
                            primeVal = false;
    
                        if ((j == L) && (primeVal))
                        {
                            B = i;
                            flagVal = true;
                            break;
                        }
                    }
                    if (flagVal)
                        break;
                }
            }
    
            if (B > 3)
                startNum = B * (B - 1) * (B - 2);
            else
                startNum = pow(B, 3);
    
            M1 = (int)((log(startNum + M) / log(B))) + 1;
    
            //create the coefficient matrix
            for (int i = 0; i < M1; i++)
            {
                for (int j = 0; j < M1; j++)
                {
                    if ((i == 0) || (i == j))
                        coeffNum[i][j] = 1;
                    else if (j > i)
                        coeffNum[i][j] = (int)((coeffNum[i][j - 1] + coeffNum[i - 1][j - 1]) % (int)B);
                    else
                        coeffNum[i][j] = 0;
                }
            }
    
            for (int n = 0; n < M; n++)
            {
                if (n == 0)
                {
                    nextNum = startNum - 1;
                    divNum = startNum / B;
                    M2 = (int)((log(nextNum) / log(B))) + 1;
                }
    
                //produce the expansion series
    
                Q = nextNum;
    
                for (int i = 0; i < M2; i++)
                {
    
                    E[i] = fmod(Q, B);
                    Q = floor(Q / B);
                }
    
                //generate the Faure sequence
                for (int i = 0; i < S; i++)
                {
                    X = 0;
    
                    if (i == 0)
                    {
                        for (int j = 0; j < M2; j++)
                        {
                            A = E[M2 - j - 1];
                            X = A + X / B;
                        }
    
                        X /= B;
                    }
                    else
                    {
                        Y = 1 / B;
    
                        for (int k = 0; k < M2; k++)
                        {
                            Z = 0;
                            for (int j = 0; j < M2; j++)
                            {
                                if (j >= k)
                                    Z += E[j] * coeffNum[k][j];
                            }
    
                            A = fmod(Z, B);
                            E[k] = A;
    
                            X += Y * A;
                            Y /= B;
                        }
                    }
                    //cout << "前置b" << sizeof(R) / sizeof(double) << endl;
                    ////*(*(R + n) + i) = X;
                    R[n][i] = X;
                 //   cout << "后置b" << sizeof(R) / sizeof(double) << endl;
                }
    
                nextNum++;
    
                if (fmod(nextNum, divNum) == 0)
                {
                    divNum *= B;
                    M2++;
                }
            }
            double d = 123456;
    
            return d;
        }
    
         double RandomNumberService::GenerateInverseRandomNumber(double X) 
        {
            cout << X << endl;
            //double X = 3.0;
            double A1 = 0.31938153;
            double A2 = -0.356563782;
            double A3 = 1.781477937;
            double A4 = -1.821255978;
            double A5 = 1.330274429;
            double D = 0.2316419;
            double K, DK, Y, Z, XX, YY, ZZ;
    
            //CALCULATIONS OF INVERSE OF CUMULATIVE STANDARD NORMAL DISTRIBUTION WITH NEWTON-RAPHSON ALGORITHM
    
            Z = X;
    
            if (Z >= 0.5)
                X = 0.5;
            else
                X = -0.5;
    
            for (int i = 0; i < 10000; i++)
            {
                if (X >= 0.0)
                {
                    ZZ = exp(-X * X / 2) / sqrt(2 * M_PI);
    
                    K = 1 / (1 + D * X);
    
                    DK = -D / pow(1 + D * X, 2);
    
                    XX = 1 - ZZ * (A1 * K + A2 * K * K + A3 * K * K * K + A4 * pow(K, 4) + A5 * pow(K, 5));
    
                    YY = ZZ * (A1 * (K * X - DK) + A2 * K * (K * X - 2 * DK) + A3 * K * K * (K * X - 3 * DK) + A4 * pow(K, 3) * (K * X - 4 * DK) + A5 * pow(K, 4) * (K * X - 5 * DK));
                }
                else
                {
                    ZZ = exp(-X * X / 2) / sqrt(2 * M_PI);
    
                    K = 1 / (1 - D * X);
    
                    DK = D / pow(1 - D * X, 2);
    
                    XX = ZZ * (A1 * K + A2 * K * K + A3 * K * K * K + A4 * pow(K, 4) + A5 * pow(K, 5));
    
                    YY = ZZ * (A1 * (-K * X + DK) + A2 * K * (-K * X + 2 * DK) + A3 * K * K * (-K * X + 3 * DK) + A4 * pow(K, 3) * (-K * X + 4 * DK) + A5 * pow(K, 4) * (-K * X + 5 * DK));
                }
    
                Y = X - (XX - Z) / YY;
    
                if (abs(Y - X) <= 0.0001)
                    break;
    
                X = Y;
            }
            cout << "1234" << endl;
            return round(X, 3);
            // return 11111;
        }
    
    //}
  • 相关阅读:
    快排
    SQL实例
    14_可变字符串类和日期相关类
    13_String类的概述和使用
    c# json object Dictionary互转
    SQL Server 数据表给现有字段添加默认值或修改默认值
    SQL Server2008R2 死锁进程杀掉处理
    Sql Server 2008R2 查看SQL语句运行时间
    fatal: unable to access 'https://github.com/xxx': OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443
    idea出现了不能复制的问题
  • 原文地址:https://www.cnblogs.com/kexb/p/5569476.html
Copyright © 2020-2023  润新知