Thanks so much for the tips; I have some follow-up questions:
"MM" == Mikael More mikael.more@gmail.com writes:
MM> - Throwing exceptions with no handler/catcher may sigsegv your MM> app.
Good to know, I was unaware of this.
MM> - You should presuppose that ___argXX variables inside MM> Scheme-to-C calls are trashed after C-to-Scheme calls. I.e.: If MM> you have declared a c-define or c-lambda that takes parameters, MM> these will appear as ___arg0, ___arg1 etc. in the C code of the MM> c-define / c-lambda. These will have correct contents all until MM> you invoke Scheme functions from the C code. not afterwards.
Okay, take the following functions, that may be the source of the problem:
/* C function for transferring vectors */ int f64vector_length (___SCMOBJ); double f64vector_ref (___SCMOBJ, int); double * scm_vector_to_C (___SCMOBJ f64vec) { /* initialize the length of the vector */ int len = f64vector_length (f64vec); /* initializes the new vector */ double * newCvec = malloc (len*sizeof (double)); /* declare a counter */ int i; /* iterate over the length of the vector copying each object into the new vector */ for (i = 0; i<len; i++) { /* could be re-written using pointer arithmetic */ newCvec[i] = f64vector_ref (f64vec, i); } return newCvec; }
and then the corresponding "c-define"s:
;; Scheme function for getting data out of f64vectors (c-define (proc1 f64vec i) (scheme-object int) double "f64vector_ref" "" (f64vector-ref f64vec i)) (c-define (proc2 f64vec) (scheme-object) int "f64vector_length" "" (f64vector-length f64vec))
MM> So back them up to the stack if you do.
Forgive my ignorance of C, but how do I do that? (where the heck is this stack that everyone speaks of?)
Now, I also noticed this passage in the C-interface chapter of the manual:
,---- | Within the C code the variables `___arg1', `___arg2', etc. can be | referenced to access the converted arguments. Similarly, the result to | be returned from the call should be assigned to the variable `___result' | except when the result is of type `struct', `union', `type', `pointer', | `nonnull-pointer', `function' or `nonnull-function' in which case a | pointer must be assigned to the variable `___result_voidstar' which is | of type `void*'. For results of type `pointer', `nonnull-pointer', | `function' and `nonnull-function', the value assigned to the variable | `___result_voidstar' must be the pointer or function cast to `void*'. `----
However, I have functions like this:
(define make-gsl-matrix (c-lambda (int int scheme-object) gsl-matrix* "gsl_matrix * ___matrix = gsl_matrix_alloc (___arg1, ___arg2); ___matrix->data = scm_vector_to_C (___arg3); ___matrix->size1 = ___arg1; ___matrix->size2 = ___arg2; ___result_voidstar = ___matrix;"))
It seems that this is seriously wrong, according to the paragraph above: the last line should be
___result_voidstar = (void*)___matrix;
and the return type should be void* and not gsl-matrix*, defined as follows:
(c-define-type gsl-matrix* (pointer "gsl_matrix" gsl-matrix*))
But then the question becomes how do I access the result I need? I would much rather have a function that returns a matrix as a result (functional style) rather than having it imperatively modify an existing variable, a la C.
Thanks for your help! Joel