
Ok, smidiff clarifies the use of smiInit more concisely, never had occasion to use it, thanks for the pointer to that program. The usage is less muddy with that example, so smiInit - according to that example can be called more than once.
smiInit, can be called multiple times, for each individual parse tree as needed and tag:dataset, which basically maintains an internal reference or 'handle' as the code infers.
Having said that, in regards to smidiff, smiInit, is called more than 2 times in the same code, i.e. one has 'oldtag' and 'newtag', which also provokes other questions...
So every time smiInit is called, it parses, the MIB, in the case of smidiff. So, if one called 'smiInit("myMib") and 'smiInit("otherMib")', smiInit simply parses that mib. Which seems to be the case, in smidiff.
To clarify a bit, of the questions I am asking, in the past when I used libsmi, I loaded all of the mibs (SMI) in the smirc, one time, at startup, as it was my thought, that I only wanted to parse what I was using, one time, at start up, since if one loaded many times throughout the program, from an efficiency standpoint, one would induce many 'parse' actions, which, in my train of thought, at the time was unnecessary overhead for the project I used it in. Of course the trade off would be a larger memory footprint while running, since everything loaded for parsing, would be maintained in memory, for the duration of the program.
So since memory was plentiful, I did not think the less efficient method of loading and unloading throughout the life of the program, was necessarily a trade off I wanted in my implementations. I/O (reading/writing of files/sockets) is more expensive in terms of efficiency, than parsing every thing one time at startup. So, I elected to go with one time parsing.
As far as a 'problem' there really is none, as I have used libsmi successfully in a few projects as it is. It works. But a keen understanding of how the original authors intended it to be used is very much of benefit to further leverage it.
To further elaborate, the reason I asked for clarification is basically for the following reasons:
1) There was mention of a C++ wrapper, which I have developed, using the man pages of the C functionality, it is not ready for prime time (yet), as I have yet to test all of it's functionality against the C functionality intended. I.e. when I use a library, in general, I implement functions as they are needed against their prescribed usage. Having said that, when implementing a C++ wrapper, it is important that the C++ code applies the underlying C code in the context it was intended. So testing and understanding of each of the C functions and their intended use is paramount (IMO). The intention is not to change how libsmi works, but provide a C++ layer that works on top of it.
2) Thread safe... In object oriented land, I do use threads, a lot. So basically, part of the wrapper, is to address this, without having to change code in libsmi. The intent is not necessarily to provoke the original authors to change all of the C code to be thread safe, but to add some level of thread safe operation in the C++ layer...
That is the intent of my questioning... As a side note, doing the C++ whether it is chosen by the author(s) to implement, there is a small name space problem with the existing implementation...
The compiler(s) used, are gcc/g++, when compiling using g++ and including the smi.h, I encountered the following:
1) There are references in a few lines of code, that refer to 'extern SmiClass' and take pointers to 'char *class', in C++ 'class' is a reserved word, so these references were changed from 'class' to 'clazz' so the C++ compiler was happy, it did not change the functionality of the original underlying C functions. (it doesn't care anyway, all it is really looking for is a character pointer).
If it is desired, I will supply a diff with these ever so minor changes. Personally, I would consider this a patch, be it minor, but it also makes the C++ compiler happy.
So, what is to be gained by wrapping in C++? Well, I would submit the following for consideration...
1) libsmi works, at C code level (I say this, simply because, IMO, no code is perfect, not mine, nor MicroSloths', or whoevers'), so it is VERY important to understand the author's mindset. The benefit is that any useful code that addresses an issue, as in the case of libsmi, is beneficial - I use it, it works.
2) A well debugged C++ wrapper that deals with these issues, will require less code to be written, in my 20+ years of programming, the one thing I have found that is true, the more lines you write, the more error prone it becomes, so less implementation code = less implementation errors. That is not to say that a wrapper is simple in nature, but only to say that it, in and of itself addresses an issue I believe to be important, in the very least, at the level I intend to leverage libsmi.
Being clever, is an exercise of implementation of functions, having said that, being too clever, is a function of ego, not practicality. What code I write, my end goal is to have VERY low maintenance code, that gets results, as efficiently as possible.
On 12/11/2010 10:01 AM, Juergen Schoenwaelder wrote:
On Sat, Dec 11, 2010 at 09:24:18AM -0600, Mark Martin wrote:
I have used libsmi for a couple of projects, having said that, the one thing I have discovered in regards to smiInit (this is proven with the sample progam, smiInit takes an argument, or NULL, using NULL, it will not dump the OID tree, except for the first node, then nothing else follows... except the remaining numbers. However, if you put something (doesn't matter what) as a char * argument, the tree parse works. I have looked at the manual page many times, and even looked at the 'C' code for smiInit, and I am not sure of the full functionality of the argument, other than it adds a 'handle' in the init function, all the the man page says is 'tag:dataset' I am not sure what this means in the context it is implemented.
Can someone provide more insight, as to how and why someone would used this, by a more practical explanation?
I can pass "x", and the parse works, no "x:yyy", so I am not sure what this parameter would be used for other than it actually parsing the mib tree.
Here is the man page text:
The smiInit() function should be the first SMI function called in an application. It initializes its internal structures. If tag is not NULL, the global configuration file and (on UNIX systems) a user con‐ figuration file are read implicitly, if existent. All global statements and those statements with a tag (a ‘‘tag: ’’ prefix) that matches the tag argument are executed. (see also CONFIGURATION FILES below). smi‐ Init() returns zero on success, or otherwise a negative value. The smiInit() function can also be used to support multiple sets of MIB data. In this case, the tag argument may be prepended by a colon and a name to differentiate the data sets. Any library function call subse‐ quent to an smiInit("tag:dataset") call is using the specified data set.
Perhaps it is not the best text. But then, from your description, it is also difficult to infer what your specific problem is. In most circumstances, you simply use smiInit(NULL) or smiInit("myfancyapp"). The "tag:dataset" notation is only relevant if your program needs to maintain multiple independent parse trees, like for example smidiff.
/js