From help-octave-request at bevo dot che dot wisc dot edu Thu Feb 1 19:47:39 2001 Subject: Dynamically linked C/C++ functions and file descriptor From: "John W. Eaton" To: Joshua Rigler Cc: Help-Octave Date: Thu, 1 Feb 2001 19:47:32 -0600 On 1-Feb-2001, Joshua Rigler wrote: | 1) Suppose I create a dynamically linked C++ function using mkoctfile. | This function dynamically allocates some memory, and sets a static | pointer for this memory location (using calloc). The function exits, | and I'm returned to Octave. I call that function again. Can I assume | that the static pointer is still valid and points to the proper place in | memory, as it would if I was simply calling the function from another | C++ function? Yes, unless you have unloaded (cleared) the function between calls. | 2) Maybe related...suppose I have a C++ function that generates a void | pointer file descriptor (i.e. typedef void *CDFid). If I return that | file descriptor to the parent Octave session, then use it in subsequent | calls to other dynamically linked functions that use it, is that pointer | still valid? Yes, but whether it points to anything valid depends on what you've done with the storage that it points to between calls. | 3) Finally, how the heck can I return a pointer to Octave? It doesn't | seem to like anything but double floats and strings (and vectors, | arrays, and complex versions of such). Could I perhaps pass back a | string of the hexidecimal format of the pointer, and then pass this | between function calls, which would convert the string to the real | pointer/address...is this even possible? You could just try to stuff the pointer into a double, but that could cause exceptions (not all pointer values are guaranteed to be valid double values on all systems, I think, so you might generate a floating point exception). You could define a new data type for your pointer type, but that would be a lot of work. Or, you could maintain a static array of your integers and then return the index into the array to the caller. When someone passes you an integer, you look up the pointer in the array. This is essentially how Octave deals with streams. | // Copy string from args into a charactar array that can be | // read by CDFopen | int flength = args(0).string_value().length(); | CDFname = (char *)(calloc(flength,sizeof(char))); | strcpy(CDFname,args(0).string_value().c_str()); Bad things will happen in this code if args(0) is not a string. You can also extract the name without calloc and strcpy. | // Make call(s) to CDFlib | status = CDFopen (CDFname, &id); | if (status != CDF_OK) printf ("\nError, status: %d\n",status); Better to use error(). Here is more or less how I would write it, I think. // cdf_open -- function to open a CDF file and return the file descriptor // (this is a dynamically linked function for Octave, written in C++) // // Usage: id = CDF_OPEN('filename.cdf'); #include extern "C" { #include } DEFUN_DLD (cdf_open, args, nargout, "id = CDF_OPEN ('filename.cdf');\n\ \n\ Open a file.;\n\ ... other CDF_ commands ...") { octave_value retval; if (args.length () == 0 || nargout > 1) print_usage ("cdf_open"); else { char *CDFname; // pointer for Variable length CDF filename std::string fname = args(0).string_value (); if (! error_state) { // I assume that CDFopen does not need to modify the // filename argument. If CDFopen is declared to take const // char* for fname, this will work. If it is char*, then // you will either have to fix CDF, or copy fname.c_str () // to some temporary storage (Octave's library has an // strsave function, declared in lo-utils.h, that is useful // for this purpose). CDFid id; CDFstatus status = CDFopen (fname.c_str (), &id); if (status == CDF_OK) { // Do whatever you need to keep IDs in an array, and // return an index to the new ID. // ... } else { error ("CDFopen failed, status: %d", status); retval = -1.0; } } } return retval; } jwe ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------