zoukankan      html  css  js  c++  java
  • 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;
        }
    
    //}
  • 相关阅读:
    Spring Boot 使用 Dom4j XStream 操作 Xml
    Spring Boot 使用 JAX-WS 调用 WebService 服务
    Spring Boot 使用 CXF 调用 WebService 服务
    Spring Boot 开发 WebService 服务
    Spring Boot 中使用 HttpClient 进行 POST GET PUT DELETE
    Spring Boot Ftp Client 客户端示例支持断点续传
    Spring Boot 发送邮件
    Spring Boot 定时任务 Quartz 使用教程
    Spring Boot 缓存应用 Memcached 入门教程
    ThreadLocal,Java中特殊的线程绑定机制
  • 原文地址:https://www.cnblogs.com/kexb/p/5569476.html
Copyright © 2011-2022 走看看