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;
    }

//}

 

posted on 2016-06-08 11:22  听哥哥的话  阅读(379)  评论(0编辑  收藏  举报

导航