Can I use sprintf in a reentrant function if it writes in a local buffer? Something like this:
void reentrant_function () {
int i = 4;
char buffer[20];
snprintf(buffer, 20, "%d", i);
}
I get to this page because I am also asking the same question. Here is what I read from books:
Advanced Programming in the UNIX Environment: Second Edition
Section 10.6
Most functions that are not in Figure 10.4 (a list of reentrant functions) are missing because (a) they are known to use static data structures, (b) they call malloc or free, or (c) they are part of the standard I/O library.
The Linux Programming Interface
Chapter 21.1.2
Functions can also be nonreentrant if they use static data structures for their
internal bookkeeping. The most obvious examples of such functions are the members
of the stdio library (printf(), scanf(), and so on), which update internal data
structures for buffered I/O.
I guess it is implementation depending. It also depends on how do you use snprintf actually (the buffer is essential). The safest answer to the question should be 'no'.
Sure you can, unless your buffer is static.
Yes.
Why do you think you could not? There's no global.
One thing thought: the buffer is local to the function, why would you want to format a string and do nothing with it?
Related
I working on a constrained embedded system.
Presently we use snprintf to a buffer, then with another statement, print the buffer to the serial port:
char temp_buffer[256];
int bytes_written = snprintf(temp_buffer, sizeof(temp_buffer),
"Solar system has %d planets\n",
10);
if (bytes_written > 0)
{
Serial_Port_Output(temp_buffer, bytes_written);
}
I want to switch to printf to write directly to the serial port. Per our compiler's documentation, I have intercepted the function call for outputting the data to use the serial port. (The interface uses block writing: an address and the number of characters).
The printf function may use a character buffer for formatting, such as integer or floating point to text.
Questions:
Where is the buffer that printf uses for formatting? (Other
inquiring minds want to know, before I make the changes.)
Is this a compiler (platform) dependent issue?
Platform: Arm7tdmi processor, System On a Chip (SOC), IAR EW compiler.
This is completely implementation-specific. printf is under no obligation to use any buffer. Of course it has at its disposal the stdio buffer associated with the FILE (stdout in the case of printf) but that may be zero-length if the program turned off buffering with setbuf/setvbuf. It's also possible that printf has an internal buffer; for a proper C implementation this would need to have automatic storage ("on the stack") but a low-quality embedded one without threads might use a static buffer. In any case, printf is specified to work as if by repeated calls to fputc, and it could certainly be implemented this way without any buffer at all.
It is library rather than compiler dependent and you should consult the library's documentation and possibly where available the source code. This (perhaps out-of-date) IAR C Library documentation says:
Since a complete formatter demands a lot of space there are several
different formatters to choose between. For more information, see the
see the IAR C Compiler Reference Guide.
The current IAR compiler reference discusses formatter selection, though in most cases the linker can automatically select the most appropriate formatter. The documentation even discusses further optimisation available if rebuilding the library (for which you presumably need a source license).
Some implementations (not specifically IAR) use significant stack space. If you want full control, you might consider using an open-source implementation such as Tiny printf. It is not a complete ISO implementation, but suitable for many embedded applications.
The scandir() function scans the directory dir, calling
select() on each directory entry as "int(*filter)(const struct dirent *)"
How can I pass pattern value as parameter to fnmatch(const char *pattern, const char *string, int flags) function used in filter ?
Here my sample code
int my_selectgrf(const struct dirent *namelist)
{
int r = 0;
char my_pattern[] = "*.grf";
r = fnmatch(my_pattern, namelist->d_name, FNM_PERIOD);
return (r==0)?1:0;
}
scandir("/pub/data/grf", &namelist, my_selectgrf, alphasort);
my goal is to be able to use my_pattern as input parameter.
The short answer: You can't. This is an atrociously bad API, and it's outright shameful that something like this was added to POSIX as recently as 2008 (based on a bad design in glibc). This kind of API without a way to parameterize it or pass it a context should have been abolished 20+ years ago.
With that said, there are some workarounds:
Approach 1: Use a global variable, and if your code needs to be thread-safe, ensure that only one thread can be using scandir with the given scan function at a time, by locking. This of course serializes usage, which is probably not acceptable if you actually want to be calling the function from multiple threads.
Approach 2: Use thread-local storage, either the GCC __thread keyword (or the C11 _Thread_local keyword, which GCC sadly still does not accept) or POSIX pthread_setspecific and family. This is fairly clean, but unfortunately it may not be correct; if the implementation of scandir internally used multiple threads, the parameter could fail to be available in some calls back to the scan function. At present, I don't believe there are multi-threaded implementations of scandir.
Now, the better solution:
Ditch scandir and write your own function to do the same thing, with the proper API. It's only a few lines anyway.
Dearest stack exchange,
I'm programming an MRI scanner. I won't go into too much background, but I'm fairly constrained in how much code I've got access to, and the way things have been set up is...suboptimal. I have a situation as follows:
There is a big library, written in C++. It ultimately does "transcoding" (in the worst possible way), writing out FPGA assembly that DoesThings. It provides a set of functions to "userland" that are translated into (through a mix of preprocessor macros and black magic) long strings of 16 bit and 32 bit words. The way this is done is prone to buffer overflows, and generally to falling over.*
The FPGA assembly is then strung out over a glorified serial link to the relevant electronics, which executes it (doing the scan), and returning the data back again for processing.
Programmers are expected to use the functions provided by the library to do their thing, in C (not C++) functions that are linked against the standard library. Unfortunately, in my case, I need to extend the library.
There's a fairly complicated chain of preprocessor substitution and tokenization, calling, and (in general) stuff happening between you writing doSomething() in your code, and the relevant library function actually executing it. I think I've got it figured out to some extent, but it basically means that I've got no real idea about the scope of anything...
In short, my problem is:
In the middle of a method, in a deep dark corner of many thousands of lines of code in a big blob I have little control over, with god-knows-what variable scoping going on, I need to:
Extend this method to take a function pointer (to a userland function) as an argument, but
Let this userland function, written after the library has been compiled, have access to variables that are local to both the scope of the method where it appears, as well as variables in the (C) function where it is called.
This seems like an absolute mire of memory management, and I thought I'd ask here for the "best practice" in these situations, as it's likely that there are lots of subtle issues I might run into -- and that others might have lots of relevant wisdom to impart. Debugging the system is a nightmare, and I've not really got any support from the scanner's manufacturer on this.
A brief sketch of how I plan to proceed is as follows:
In the .cpp library:
/* In something::something() /*
/* declare a pointer to a function */
void (*fp)(int*, int, int, ...);
/* by default, the pointer points to a placeholder at compile time*/
fp = &doNothing(...);
...
/* At the appropriate time, point the pointer to the userland function, whose address is supplied as an argument to something(): /*
fp= userFuncPtr;
/* Declare memory for the user function to plonk data into */
i_arr_coefficients = (int) malloc(SOMETHING_SENSIBLE);
/* Create a pointer to that array for the userland function */
i_ptr_array=&i_arr_coefficients[0];
/* define a struct of pointers to local variables for the userland function to use*/
ptrStrct=createPtrStruct();
/* Call the user's function: */
fp(i_ptr_array,ptrStrct, ...);
CarryOnWithSomethingElse();
The point of the placeholder function is to keep things ticking over if the user function isn't linked in. I get that this could be replaced with a #DEFINE, but the compiler's cleverness or stupidity might result in odd (to my ignorant mind, at least) behaviour.
In the userland function, we'd have something like:
void doUsefulThings(i_ptr_array, ptrStrct, localVariableAddresses, ...) {
double a=*ptrStrct.a;
double b=*ptrStrct.b;
double c=*localVariableAddresses.c;
double d=doMaths(a, b, c);
/* I.e. do maths using all of these numbers we've got from the different sources */
storeData(i_ptr_array, d);
/* And put the results of that maths where the C++ method can see it */
}
...
something(&doUsefulThings(i_ptr_array, ptrStrct, localVariableAddresses, ...), ...);
...
If this is as clear as mud please tell me! Thank you very much for your help. And, by the way, I sincerely wish someone would make an open hardware/source MRI system.
*As an aside, this is the primary justification the manufacturer uses to discourage us from modifying the big library in the first place!
You have full access to the C code. You have limited access to the C++ library code. The C code is defining the "doUsefullthings" function. From C code you are calling the "Something" function ( C++ class/function) with function pointer to "doUseFullThings" as the argument. Now the control goes to the C++ library. Here the various arguments are allocated memory and initialized. Then the the "doUseFullThings" is called with those arguments. Here the control transfers back to the C code. In short, the main program(C) calls the library(C++) and the library calls the C function.
One of the requirements is that the "userland function should have access to local variable from the C code where it is called". When you call "something" you are only giving the address of "doUseFullThings". There is no parameter/argument of "something" that captures the address of the local variables. So "doUseFullThings" does not have access to those variables.
malloc statement returns pointer. This has not been handled properly.( probably you were trying to give us overview ). You must be taking care to free this somewhere.
Since this is a mixture of C and C++ code, it is difficult to use RAII (taking care of allocated memory), Perfect forwarding ( avoid copying variables), Lambda functions ( to access local varibales) etc. Under the circumstances, your approach seems to be the way to go.
is it possible to wrap a c++ library into c?
how could i do this?
are there any existing tools?
(need to get access to a existing c++ library but only with C)
You can write object-oriented code in C, so if it's an object-oriented C++ library, it's possible to wrap it in a C interface. However, doing so can be very tedious, especially if you need to support inheritance, virtual functions and such stuff.
If the C++ library employs Generic Programming (templates), it might get really hairy (you'd need to provide all needed instances of a template) and quickly approaches the point where it's just not worth doing it.
Assuming it's OO, here's a basic sketch of how you can do OO in C:
C++ class:
class cpp {
public:
cpp(int i);
void f();
};
C interface:
#ifdef __cplusplus
extern "C" {
#endif
typedef void* c_handle;
c_handle c_create(int i)
{
return new cpp(i);
}
void c_f(c_handle hdl)
{
static_cast<cpp*>(hdl)->f();
}
void c_destroy(c_handle hdl)
{
delete static_cast<cpp*>(hdl);
}
#ifdef __cplusplus
}
#endif
Depending on your requirements, you could amend that. For example, if this is going to be a public C interface to a private C++ API, handing out real pointers as handles might make it vulnerable. In that case you would hand out handles that are, essentially, integers, store the pointers in a handle-to-pointer map, and replace the cast by a lookup.
Having functions returning strings and other dynamically sized resources can also become quite elaborate. You would need the C caller provide the buffer, but it can't know the size before-hand. Some APIs (like parts of the WIn32 API) then allow the caller to call such a function with a buffer of the length 0, in which case they return the length of the buffer required. Doing so, however, can make calling through the API horribly inefficient. (If you only know the length of the required buffer after the algorithm executed, it needs to be executed twice.)
One thing I've done in the past is to hand out handles (similar to the handle in the above code) to internally stored strings and provide an API to ask for the required buffer size, retrieve the string providing the buffer, and destroy the handle (which deletes the internally stored string).
That's a real PITA to use, but such is C.
Write a c++ wrapper that does an extern c, compile that with c++, and call your wrapper.
(don't “extern c”)
extern C only helps you to have a names in dll like you see them.
You can use
dumpbin /EXPORTS your.dll
to see what happens with names with extern C or without it.
http://msdn.microsoft.com/en-us/library/c1h23y6c(v=vs.71).aspx
To answer your question... It depends... But it is highly unlikely that you can use it without wrappings. If this C++ library uses just a simple functions and types you can just use it. If this C++ library uses a complex classes structure - probably you will be unable to use it from C without wrapping. It is because the internal of classes may be structured one way or another depending on many conditions (using inference with virtual tables or abstracting. Or in example complex C++ library may have its own object creation mechanisms so you HAVE to use it in the way it is designed or you will get unpredictable behavior).
So, I think, you have to prepare yourself for doing dome wrappings.
And here is a good article about wrapping C++ classes. It the article the Author tells about wrapping C++ classes to C# but he uses C at first step.
http://www.codeproject.com/KB/cs/marshalCPPclass.aspx
If the C++ library is written which can be compiled with C compiler with slight editting (such as changing bool to int, false to 0 and true to 1 etc), then that can be done.
But not all C++ code can be wrapped in C. Template is one feature in C++ that cannot be wrapped, or its nearly impossible.
Wrap it in C++ cpp that calls that dll, and "extern C" in that file you made.
I have not worked with static libraries before, but now I need to.
Scenario:
I am writing a console app in Unix. I freely use std::string everywhere because it's easy to do so. However, I recently found out that I have to support it in Windows and a third party application would need API's to my code (I will not be sharing source, just the DLL).
With this in mind, can I still use std::string everywhere in my code but then provide them with char * when I code the API's? Would that work?
Yep. Use std::string internally and then just use const char * on the interface functions (which will be converted to std::strings on input.
Why not just provide them with std::string?
It's standard C++, and I'd be very suprised if they didn't support it.
The question is, what your clients will do with that pointer. It should of course be const char*, but if clients will keep and reference it later on, its probably risky to use std::string internally, because as soon as you operate yourself on the strings there is no way to keep std::string from moving memory, as its reference counting mechanism can not work with exported char* pointers. As long as you dont touch the std::string objects, their memory wont move, and the pointer is safe.
There is no standardized C++ binary interface (at least I haven;t heard about it), thus projects with different settings may appear to be unlinkable together. For example, Visual C++ provides a way to enable/disable iterator debug support. This is controlled by macro and size of some data structures depends on it.
If two codes compiled with different settings start to communicate using these data structures, the best thing you can have is linker error. Other alternatives are worse - stable run-time error, release-configuration-only error, etc...
So if you don't want to restrict your users to single correct project settings set and compiler version, use only primitive data for interface. For internal implementation choose what is more convenient.
Adding to Poita_'s response:
consider unicode support
If you ever have to support localization, too, you'll be happy to have done it in the first place
when returning char/wchar_t const *, define the lifetime of the data. The best would be to have a project-wide "unless stated otherwise..." standard
Alternatively, you can return a copy that must be freed through a method exported by your library. (C++ clients can move that into a smart pointer to regain automatic memory management.)
std::string will work in, at the very least, Visual Studio C++ (and others), so why not just use that?