Page 3 of 3
Re: C/C++ API
Posted: Fri Nov 22, 2013 2:30 pm
by hines
use either xopen or load_fiie(1, "...")
from
http://www.neuron.yale.edu/neuron/stati ... #load_file
The functionality is identical to xopen() except that the xopen takes place only if if a file of that name has not already been loaded with the load_file,
Re: C/C++ API
Posted: Sat Nov 23, 2013 3:31 am
by stephanmg
I will try this, hines.
Thank you so much.
Okay this seems reasonable, and works, but isn't there any way to automatically "reinit" the hoc interpreter? I mean I should be able to quit() the hoc interpreter, but quit() seems to call exit(0) which is not what i want, since my program then quits too!
All the best,
Stephan
Re: C/C++ API
Posted: Mon Jul 07, 2014 5:49 am
by stephanmg
Dear all,
i can use hoc_ac_ to get the double / return value of a hoc_valid_stmt execution.
How about getting a string into hoc_ac_, i. e. get for example a section name?
Could I use something like this?
Code: Select all
static double get_section_names(v) void* v;
{
char* secname();
Item* q;
List* sl = (List*)v;
ITERATE(q, sl) {
section_names.append(secname(q->element.sec));
}
return 1.;
}
And then I would call in my C++ Code:
Code: Select all
extern hoc_List* section_list; /* Where the Sections live */
std::vector<char*> section_names;
get_section_names(section_list);
Best,
Stephan
Re: C/C++ API
Posted: Mon Jul 07, 2014 7:23 am
by hines
You can get the name of the currently accessed section with
extern const char* secname(Section*);
Copy it to another string before calling it again.
There is no string variable analogous to the built-in hoc_ac_. Because the old K&R c code was generating too many warnings with modern compilers, all of the functions have been converted to
ansi style and all the prototypes are now in various *.h files in src/oc and src/nrnoc. (Someday I'd like to get around to removing every extern statement in every *.c file, replacing with the appropriate
#include statements), In particular see oc_ansi.h and nrn_ansi.h and you might be interested in
extern char* gargstr(int);
extern char** hoc_pgargstr(int);
which are often used in mod files to get and set strings (the latter through the use of
extern void hoc_assign_str(char** pstr, const char* buf); )
Alternatively, if you execute the hoc statement at the top level of the interpreter
strdef my_hoc_str_
you can get the permanent char** for my_hoc_str_ with
#include "hocdec.h"
...
char** foo = OPSTR(hoc_lookup("my_hoc_str_");
*foo will always mirror the value of my_hoc_str_
Here is an example:
Code: Select all
$ cat test.mod
NEURON { SUFFIX nothing }
VERBATIM
char** hocStrMirror;
ENDVERBATIM
PROCEDURE setup() {
VERBATIM
hoc_obj_run("strdef my_hoc_str_", 0);
hocStrMirror = OPSTR(hoc_lookup("my_hoc_str_"));
ENDVERBATIM
}
PROCEDURE prnt() {
VERBATIM
printf("%s\n", *hocStrMirror);
ENDVERBATIM
}
$ cat test.hoc
setup()
my_hoc_str_ = "hello"
prnt()
Re: C/C++ API
Posted: Mon Jul 07, 2014 7:31 am
by stephanmg
Dear hines,
thanks firstly for your quick reply.
So you mean i could use
?
I thin the Section* pointer argument was accidently wrong, right?
Best,
Stephan
Re: C/C++ API
Posted: Mon Jul 07, 2014 7:47 am
by hines
Sorry. What I left out was the function that returns the currently accessed section. That is
extern Section* chk_access(void);
Re: C/C++ API
Posted: Mon Jul 07, 2014 7:49 am
by stephanmg
hines wrote:Sorry. What I left out was the function that returns the currently accessed section. That is
extern Section* chk_access(void);
Ah thanks, I see,
so my simple functkion call would not do it, because it's also defined?
Best,
Stephan
Re: C/C++ API
Posted: Mon Jul 07, 2014 7:55 am
by hines
You can get the name of the currently accessed section with
extern Section* chk_access(void);
extern const char* secname(Section*);
ie
printf("%s\n", secname(chk_access()))
Re: C/C++ API
Posted: Mon Jul 07, 2014 8:05 am
by stephanmg
Okay,
but if i use this, then i arrive at:
Code: Select all
Undefined symbols for architecture x86_64:
"secname(Section*)", referenced from:
Edit: Okay i managed to resolve this - but now I arrive at (Note that I have not accessed any section with the access command until now):
Code: Select all
(null): Section access unspecified
near line 0
objref hoc_obj_[2]
Best,
Stephan
Re: C/C++ API
Posted: Mon Jul 07, 2014 9:19 am
by hines
If there is at least one section in existence, chk_access will not print an error message. There is a variant called
extern Section* nrn_noerr_access(void);
which will return NULL if there is no accessed section.
Re: C/C++ API
Posted: Mon Jul 07, 2014 10:13 am
by stephanmg
This is wonderful, hines.
Thanks in advance,
Stephan
Re: C/C++ API
Posted: Tue Jul 08, 2014 11:32 am
by stephanmg
Okay,
so how can i then get just the next section? :)
Sorry i can't find out for now...
I'm on C++ Code thought, so i need at way to iterate over the section and append it to the std::vector, e. g. i do this, but this is hacky, since i delete the sections.
Afterwards i just load the hoc geometry file again, which seems to work... but this is ugly, you will probably agree! :)
Any hints are welcome.
Code: Select all
std::vector<const char*> section_names;
for (int i=0; i < sections_in_hoc_file; i++) {
Section* sec = chk_access();
section_names.append(secname(sec));
hoc_valid_stmt("delete_section()");
}
This seems not to work, which I tried out at first glance:
Code: Select all
for (int k = 0; k < no_sections; k++) {
hoc_valid_stmt("j = 0", 0);
std::stringstream cmd;
cmd << "forall{ if (j == " << k << ") { {current_section.append()} {break} } { j = j + 1} }";
hoc_valid_stmt(cmd.str().c_str(), 0);
cmd.str("");
Section* sec = chk_access(); // i just get the first section in the hoc file, means no_sections times the soma section
std::cout << secname(sec) << std::endl;
cmd << "current_section.remove(current_section)";
hoc_valid_stmt(cmd.str().c_str(), 0);
}
Best,
Stephan
Re: C/C++ API
Posted: Tue Jul 08, 2014 1:21 pm
by hines
src/nrnoc/sections.h has a macro that iterates over all the sections.
hoc_Item* qsec;
ForAllSections(sec) //{ No open brace!
printf("%s\n", secname(sec));
}
Re: C/C++ API
Posted: Wed Jul 09, 2014 4:17 am
by stephanmg
Fine, thanks in advance!
So to document the solution for the original question I wanted to address, i.e. fill an std vector with all present sections, find the code below:
Code: Select all
// NEURON includes
#include "oc2iv.h"
#include "ocjump.cpp"
#include "ivocmain.cpp"
#include "section.h
// predeclare secname function
extern const char* secname(Section*);
// retrieve all section names actually
hoc_Item* qsec;
Section* sec;
std::vector<const char*> section_names;
ForAllSections(sec) // omit opening brace, due to MACRO definition! {
section_names.push_back(secname(sec));
}
I've marked an older question in this thread above in bold - which i can not figure out until today, i just want to quit the hoc interpreter really, as quit() or ctrl-d would do, bot not call exit() to exit my whole program.