Link to home
Start Free TrialLog in
Avatar of malramsay
malramsay

asked on

MultiDimArrays - What's wrong with my code?

Hi,

Is there anything wrong with this C++ code?  If not, does anyone have any idea why I'm getting the memory error message below?

**********************************

__declspec(dllexport) double __stdcall STCDO3(double ** sigma, int rowssigma)
{
   return sigma[0][0];
}

**********************************

I'm trying to call this C++ dll function from an excel VBA like this,

**********************************

Private Declare Function STCDO3 Lib "STCDO_C.DLL" _
(sigma As Double, ByVal rowssigma As Integer) As Double

Function STC() As Double
   
    Dim arrsigma(7, 1) As Double
    Dim k As Integer
    Dim l As Integer
    k = 10
    l = 20
   
    For i = 0 To 7
        arrsigma(i, 0) = k * i
        arrsigma(i, 1) = l * i
    Next
   
    STC = STCDO3(arrsigma(0, 0), 7)
   
End Function

**********************************

and when I do I get the error mesesage,

"The instruction at "0x03d915dd" referenced memory at "0x00000000". The memory could not be "read""

**********************************

Avatar of Sys_Prog
Sys_Prog
Flag of India image

Hi

I think the call to the function is incorrect

STC = STCDO3(arrsigma(0, 0), 7)


Yoiu are passing the first element of the two dim array [i.e. a double value] while in C++, the function is expecting a pointre to a pointer to a double

Amit
Avatar of malramsay
malramsay

ASKER

Hi Amit,

This microsoft page deal with this, but it's only concerning one dimensional arrays.  

http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q207/9/31.asp&NoWebContent=1&NoWebContent=1

//So, the C++ function starts like,

long __declspec (dllexport) __stdcall AddLongs_Pointer(long *plArrayOfLongs, long lElements)   {

//Whilst the VBA is

Private Declare Function AddLongs_Pointer Lib "MyStDll.dll" _
   (FirstElement As Long, ByVal lElements As Long) As Long

lSum = AddLongs_Pointer(ArrayOfLongs(0), UBound(ArrayOfLongs)+1)

//Is my C++ correct in how it is receiving the multidimarray (i.e. with **)?  If you were passing a multidimarray from another C++ function to that one, is that how you would receive and then use it?
ASKER CERTIFIED SOLUTION
Avatar of Sys_Prog
Sys_Prog
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

Oh dear.  I am going to also be sending to this C++ function multidimensional arrays that can be any number of rows by any number of columns.  I understood that when single arrays are passed between functions you have to send the size of the array as a separate variable, so the function knew the size of the array.  

I was hoping to thus send a multidimensional array with two variables - one for the rows and one for the columns.  I suppose this is not possible?  

I think I'm going to have to use SAFEARRAYS, which I really didn't want to do as they look rather complicated and I'm running out of time.  Are there any other alternatives you know about?
I do agree with u

I think SAFEARRAY's should be a better option
Look at this:

template <class T>
class Array2D
{
private:
    T*    data;
      int   dimy;
      int   dimx;

public:
    Array2D(T* d, int y, int x = -1)
         : data(d), dimy(y), dimx(x)      {}
    Array2D(T** d, int y, int x = -1)
         : data(d[0]), dimy(y), dimx(x)      {}
      T& operator() (int y, int x) {       int pos = (y * dimy + x); return data[pos]; }
      
};
                                     
void main()
{
      int   arr[3][4] = {  { 1, 2, 3, 4, }, { 1, 2, 3, 4, }, { 1, 2, 3, 4, }, };
      Array2D<int>  ia((int*)arr, 3);
      ia(3, 4) = ia(2, 5);
}

For your example it would be

__declspec(dllexport) double __stdcall STCDO3(double ** sigma, int rowssigma)
{
   Array2D<double> s(sigma, rowssigma);
   return s(0, 0);
}

Easier than SAFE_ARRAY ?

Regards, Alex



Forget the line

        ia(3, 4) = ia(2, 5);       // kaboom!!

Better

         ia(0, 1) = ia(2, 2);

I reduced the dimensions for the example. :-)

Alex