0

I have written a C++ application and within it, I need to call a math function that was written in C. The prototype looks like:

void Jacobi_Cyclic_Method(double *eigenvalues, double *eigenvectors, double *A, int n);

My problem is that I can't seem to pass the function double * (for instance both eigenvectors and A are multi-dimensional arrays. The C++ way to pass those things seems to be

double [][size]

I have read about extern C but I don't think it applies here since I am not interfacing with an object but with source itself. How can I send that C function my multi-dimensional arrays defined as such:

double [100][100] A;
double [100][100] eigenvectors;
double [100] eigenvalues;

Trying to compile I get:

error: no matching function for call to ‘MathEngine::Jacobi_Cyclic_Method(double 
[100], double [100][100], double [100][100], int)’
mathEngine.h:9: note: candidates are: static void    
MathEngine::Jacobi_Cyclic_Method(double*, double*, double*, int)
6
  • Are you re-compiling everything, including your math function's implementation, or are you linking to an existing compiled library? That matters a lot as to whether extern "C" matters or not Commented Apr 25, 2012 at 3:35
  • The same way that you would do it had your arrays been defined in C. Commented Apr 25, 2012 at 3:36
  • You should just be able to pass these values in directly. A double[100] is a double *, and so is a double[100][100]. What goes wrong when you try? Commented Apr 25, 2012 at 3:37
  • 7
    Your C prototype requires one-dimension arrays for eigenvalues, eigenvectors, and A. Am I missing something? Commented Apr 25, 2012 at 3:37
  • I am recompiling from it's source. When I try to compile I edited my post with what I get when I try to compile Commented Apr 25, 2012 at 3:39

2 Answers 2

1

Probably the problem is that your Jacobi_Cyclic_Method function requires the matrix to be in either column or row major format, where every column/row is stored consecutively in a single, one-dimensional array. E.g. for a row major matrix of size m x n, the elements in any given row are stored contiguously and the item in row i and column j would be at position i*n+j (for zero-based indices i and j). If the matrix is column-major, it would be at position i+j*m.

Using multi-dimensional arrays in C/C++ is often not what you want because something like

double A[100][100];

is not a two-dimensional array, but a single array of length 100 containing pointers to arrays of length 100. Consequently, the rows in A are not stored contiguously.

Sign up to request clarification or add additional context in comments.

4 Comments

Well, the method is defined here: code.google.com/p/biaxmc2/source/browse/trunk/montecarlo2/mc2/… It appears that it does indeed accept a double[][].
That's what the comments say, but the code says differently. If it accepted double[][], the argument declaration for the matrix should be double** A, not double* A. -- BTW, what kind of a person are you to chose such a disrespectful, stupid user-name?!
Wow! You know I took the name from someone I saw on a game I used to play a while back and certainly wasn't aware of the chemical warfare aspect. I was quite confused at your comment here until I looked it up. I had an avatar of a guy in an orange suit etc, etc. Certainly no offense intended, I apologize. Thank you for pointing that out.
;-) Glad you didn't choose that name knowing its meaning. Apologies too, for my harsh reaction. Any ways, I generally prefer it if people choose display names related to their real names.
0

I'm assuming that your C function requires multi-dimensional arrays for some of its parameters and that the prototype is written with pointers to doubles for the array/matrix parameters where the integer parameter indicates the size of each dimension (I guess the matrices are square?). If this is the case then you can pass a pointer to the first element of each array/matrix like this:

Jacobi_Cyclic_Methods(&eigenvalues[0], &eigenvectors[0][0], &A[0][0], 100);

Your initial attempt doesn't work because the type of, for instance, eigenvectors is double[100][100] which decays to double (*)[100], not double *.

This post addresses the issue of pointers and multi-dimensional arrays.

4 Comments

I wouldn't try this unless the function documentation states that a double[100][100] is the right format. Check if the function requires row-major or column-major matrix layout.
This makes a lot of sense, I will try it out when I get home. Thanks
This has the exact effect of casting directly to (double *). Both methods let me compile but I still had issues with how the C function thought the memory was laid out vs how it actually was. That said, this works as a solution to my original post.
When operating with matrices it's worth remembering that C and C++ store them in row- major order. Iterating over matrices in column-major order can create huge performance problems. Unless the whole matrix fits in a single cache-line you can take a cache-miss every time you increment the column index.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.