Thread: C++ Excel VBA Issue

  1. #1
    Registered User
    Join Date
    Mar 2011
    Location
    USA
    Posts
    17

    C++ Excel VBA Issue

    Hey All,

    Didn't know whether to put this here or in the C++ forum - here seems more appropriate. I've written a DLL to interface with Excel VBA code. The DLL works great, and most of the VBA works as well. The issue seems to be the last argument of the function call. No matter what value I put in there it passes this huge number to the C++ code instead of the value it's supposed to pass. If anyone can help me figure this out I'd appreciate it!

    Here's the VBA:

    Code:
    Option Explicit
    
    ' Declare the LMM Function that's in the DLL
    Declare PtrSafe Function GenCudaLMMPaths Lib "C:\Path to DLL\LMMExcel.dll" Alias "GenerateCUDALMMPaths" (xTimes#, xRates#, xVols#, xRData#, ByVal ArrLen&, ByVal NPaths&) As Long
    
    
    ' Generate LMM Paths on Click
    Sub LMM_Click()
    
        Dim Times#(), Rates#(), Vols#()
    
        Dim x As Long
        Dim y As Long
        Dim rTimes As Range
        Dim rRates As Range
        Dim rVols As Range
        Dim cell As Range
    
        Dim sz&
        sz = 15
    
        ' Resize
        ReDim Times(sz), Rates(sz), Vols(sz)
    
        ' Fill in Data
        Set rTimes = Sheets("Market").Range("C2:Q2")
    
        x = 1
        For Each cell In rTimes
            Times(x) = cell.Value
            x = x + 1
        Next
    
        Set rRates = Sheets("Market").Range("C5:Q5")
    
        x = 1
        For Each cell In rRates
            Rates(x) = cell.Value
            x = x + 1
        Next
    
        Set rVols = Sheets("Market").Range("C4:Q4")
    
        x = 1
        For Each cell In rVols
            Vols(x) = cell.Value / 10000#
            x = x + 1
        Next
    
        'Call the Function
        Dim np&
    
        np = Sheets("LMM").Range("C2").Value
    
        Dim useCuda As Boolean
    
        If Sheets("LMM").Range("C3").Value = "GPU" Then
            useCuda = True
        Else
            useCuda = False
        End If
    
        Dim rData#()
        Dim rValue
    
        ReDim rData(np * sz * (sz + 3))
    
        rValue = GenCudaLMMPaths(Times(1), Rates(1), Vols(1), rData(1), sz, np)
    
    
        If rValue = -1 Then
            'No CUDA Card
            MsgBox ("Your system doesn't have a CUDA Enabled GPU")
        ElseIf rValue = 1 Then
            'Error Occurred
            MsgBox ("An error occurred while trying to generate LMM paths")
        ElseIf rValue = 0 Then
            'Success
            ' Need to reformat return data
            Dim fmtData()
    
            ReDim fmtData(np * sz, sz)
    
            Dim i, j, k
    
            For i = 0 To np - 1
                For j = 0 To np - 1
                    For k = 0 To np - 1
                        fmtData(((i * sz) + j) + 1, k + 1) = rData(((i * sz * sz) + (j * sz) + k) + 1)
                    Next k
                Next j
            Next i
    
            'Fill in data
            Sheets("LMM").Range("A8:K" & (np * sz)) = fmtData
        Else
            'Too many requested paths for this CUDA card
            MsgBox ("In order to prevent GPU Lock-up, you cannot request more than " & rValue & " paths.")
            Sheets("LMM").Range("C2").Value = rValue
        End If
    End Sub
    Here's the DLL function:

    Code:
    int __stdcall GenerateCUDALMMPaths(double* arrTimes, double* arrRates, double* arrVols, double* retData, int ArrLength, int NPaths)
    {
    	//Check if NPaths is too big
    	int maxSims = 0;
    
    	int NP = NPaths;
    
    	int ret = 0;
    
    	cudaDeviceProp cdp;
    	cudaGetDeviceProperties(&cdp, 0);
    
    	maxSims = (cdp.maxThreadsPerMultiProcessor * cdp.multiProcessorCount);
    
    	assert(false);
    
    	if(maxSims < NP)
    	{
    		return maxSims;
    	}
    	else if(maxSims == 0)
    	{
    		return -1;
    	}
    
    	std::vector<double> vTimes = std::vector<double>();
    	std::vector<double> vRates = std::vector<double>();
    	std::vector<double> vVols = std::vector<double>();
    
    	for(int i=0; i<ArrLength; i++)
    	{
    		vTimes.push_back(arrTimes[i]);
    		vRates.push_back(arrRates[i]);
    		vVols.push_back(arrVols[i]);
    	}
    
    	//Setup Return Array
    	double*** retArr = new double**[NP];
    	for(int i=0; i<NP; i++)
    	{
    		retArr[i] = new double*[ArrLength];
    		for(int j=0; j<ArrLength; j++)
    		{
    			retArr[i][j] = new double[ArrLength];
    			for(int k=0; k<ArrLength; k++)
    			{
    				retArr[i][j][k] = 0.0;
    			}
    		}
    	}
    	
    	//Do CUDA Calc
    	bool result = LMM::generateLMMSamplePaths(vTimes, vRates, vVols, NP, retArr);
    
    	if(!result)
    	{
    		ret = 1;
    	}
    
    	//Process results to return
    	long h = 0;
    
    	for(int i=0; i<NP; i++)
    	{
    		for(int j=0; j<ArrLength; j++)
    		{
    			retData[h] = i;
    			++h;
    			retData[h] = j;
    			++h;
    			retData[h] = 0;
    			++h;
    
    			for(int k=0; k<ArrLength; k++)
    			{
    				retData[h] = retArr[i][j][k];
    				++h;
    			}
    		}
    	}
    
    
    	//Delete Results
    	for(int i=0; i<NP; i++)
    	{
    		for(int j=0; j<ArrLength; j++)
    		{
    			delete [] retArr[i][j];
    		}
    		delete [] retArr[i];
    	}
    	delete [] retArr;
    
    	//Return Results
    	return ret;
    }
    I realize the code's far from optimal and needs some cleanup, but first things first, getting the arguments passed correctly.

    Thanks!
    Last edited by DougD720; 03-26-2014 at 02:21 PM.

  2. #2
    Registered User MilleniumFalcon's Avatar
    Join Date
    Feb 2014
    Posts
    33
    You do realize that cleaning up this code may help you solve your problem? No one is going to sort through this code to find some generic issue of a "huge number". You should post more details about the result you are expecting and the output you are receiving.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The VBA code is declares that the last two arguments of the DLL function are passed by reference. The C++ definition specifies that those arguments are integers passed by value.

    The two need to match.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Number Truncation Issue With Exponential Numbers From Excel
    By polydegmon in forum C# Programming
    Replies: 4
    Last Post: 03-22-2011, 04:26 PM
  2. bandwidth issue / network issue with wireless device communication
    By vlrk in forum Networking/Device Communication
    Replies: 0
    Last Post: 07-05-2010, 11:52 PM
  3. C++ Dll for Excel VBA
    By Kesslers in forum C++ Programming
    Replies: 5
    Last Post: 06-25-2010, 03:42 AM
  4. ADO .NET and Excel in C#
    By Pete_O in forum C# Programming
    Replies: 2
    Last Post: 09-13-2007, 04:12 PM
  5. C++ and MS Excel
    By AML24 in forum C++ Programming
    Replies: 2
    Last Post: 06-05-2006, 08:16 PM