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