C/C++ API

Anything that doesn't fit elsewhere.
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post 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,
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post 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
Last edited by stephanmg on Wed Jul 09, 2014 4:40 am, edited 1 time in total.
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post 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
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post 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()
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

Dear hines,

thanks firstly for your quick reply.

So you mean i could use

Code: Select all

extern const char* secname();
?
I thin the Section* pointer argument was accidently wrong, right?

Best,
Stephan
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post by hines »

Sorry. What I left out was the function that returns the currently accessed section. That is
extern Section* chk_access(void);
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post 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
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post 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()))
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post 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
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post 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.
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post by stephanmg »

This is wonderful, hines.

Thanks in advance,
Stephan
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post 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
hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: C/C++ API

Post 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));
}
stephanmg
Posts: 68
Joined: Tue Jul 03, 2012 4:40 am

Re: C/C++ API

Post 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.
Post Reply