include c++ header (fstream) from c based code? - c++

I'm modifying an open source code(pngcrush) and want to include some c++ header (fstream,iostream)
Make complains there are no such files.
How do I include them?
Thank you
-EDIT-
adler32.c:60: error: ‘uLong adler32’ redeclared as different kind of symbol
zlib.h:1469: error: previous declaration of ‘uLong adler32(uLong, const Bytef*, uInt)’
adler32.c:60: error: ‘adler’ was not declared in this scope
adler32.c:60: error: ‘buf’ was not declared in this scope
adler32.c:60: error: ‘len’ was not declared in this scope
adler32.c:64: error: expected unqualified-id before ‘{’ token
adler32.c:12: warning: ‘uLong adler32_combine_(uLong, uLong, long int)’ declared ‘static’ but never defined
make: *** [adler32.o] Error 1
Compilation exited abnormally with code 2 at Wed Jan 5 18:51:02
at code
uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;
{
unsigned long sum2;
unsigned n;
second edit -
I ended up compiling it as c code (using gcc) but with #ifdef __cplusplus extern "C"{} #endif .. I put that #ifdef following other c codes of the projects.
It compiles now, but with an warning (ranlib has no symbols, i googled it, looks like it only happens in mac os)
ar rcs libpngcrush.a png.o pngerror.o pngget.o pngmem.o pngpread.o pngread.o pngrio.o pngrtran.o pngrutil.o pngset.o pngtrans.o pngwio.o pngwrite.o pngwtran.o pngwutil.o adler32.o compress.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o simplepngcrush.o
/usr/bin/ranlib: file: libpngcrush.a(pngpread.o) has no symbols
also, when I link this libpngcrush.a to my c++ code,
it dies when I call the function that's in the library for the first time.
Run till exit from #0 0x0000000100089071 in simplepngcrush () at tokenlist.h:118
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x00000001000890f8 in simplepngcrush () at tokenlist.h:118
Looks like, I can't even get to the first line of the called function.

You cannot. C++ source code cannot be use from C.
The only way is to switch to C++: transform your C code in C++ (this often requires no or little modification to the code, only to the build scripts in order to switch compiler) and then use C++ header and tools.
EDIT:
C++ uses a different way than C to identify symbols (functions, variable and stuff).
uLong ZEXPORT adler32(adler, buf, len) is just called adler32 by C, while it could be called _Z7adler32lPKci in C++. This is to provide stuff like overloading.
If you want to let the compiler give it the same name that C gives, you can put the declaration in an extern "C":
extern "C"
{
uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len);
}

I would advise against it. If the project is written in C, keep it in C and use FILE* and printf etc.
There is a difference however if you are integrating C++ with C and want to either:
- write a module in C++ but give it a C interface
- write a module in C++ and call a C interface.
Although you could expose fstream to C by giving iostream a C interface I do not really see a great advantage in doing it. You cannot overload streaming out functions, for example (i.e. using the same name with different types being printed).
For your own code though in your own library, you may well wish to write in C++ and give it a C interface. In such a case you use forward-declarations of your classes (calling them struct) and free-functions that access it using pointers, of course, as C does not have references.
Users always deal with pointers to your class and of course they need a function to dispose of them (they don't just call free).

your C code will be compiled with a C compiler that will not recognise things like class, template, new, delete etc so there is no way to use the C++ library from C
You are likely to also encounter errors if you try compile your C code as C++ due to a stricter type system. Also your colleagues may not appreciate you transforming a C module to C++.
try to achieve your goal using C file io and C streams; FILE, fopen, fread, fwrite, fprintf, stdout, stderr etc

You don't. If the code is C, you cannot just throw C++ headers in and expect it to work. C and C++ are two different languages altogether.
Instead, move to building the entire thing in C++, which may well involve not-insignificant changes to the codebase, depending upon how it's written.
(This isn't a recommendation; it's just the only way you'll be able to use those headers. Instead, if it's written in C, stick to C. Then it'll remain maintainable with the original codebase.)

Related

C equivalent of IOMemoryDescriptor class

I'm writing some C code using IOKit, and need to use IOMemoryDescriptor methods. Unfortunately, I can only compile pure C sources, and that is a C++ class. So, I'm asking if there is some C interface that lets me perform the same operations.
Specifically, I want a function that does pretty much this, but that can be compiled as C:
#include <IOKit/IOMemoryDescriptor.h>
extern "C" void CopyOut(mach_vm_address_t src, void *dst, size_t size)
{
IOMemoryDescriptor *memDesc;
memDesc = IOMemoryDescriptor::withAddressRange(src, size, kIODirectionOut, current_task());
// Error checking removed for brevity
memDesc->prepare();
memDesc->readBytes(0, dst, size);
memDesc->complete();
memDesc->release();
}
Being based on BSD, xnu has inherited some of BSD's kernel APIs, including the copyin and copyout functions. They are declared in libkern.h, and they do pretty much what you're using an IOMemoryDescriptor for, but nothing else.
You do mention you're using IOKit - if you need anything beyond this out of IOKit's functionality, you'll pretty much have to go with a C++ compiler, or use C to call mangled names directly.
If you're new to using a weird compiler for building kexts, I'll just warn you that kernel code for x86_64 must not use the red zone of the stack, as that can't exist due to interrupt handling. If your compiler assumes a red zone is present, you'll get bizarre crashes. Clang and gcc have corresponding flags for disabling the red zone. (-mno-red-zone, if I remember correctly, automatically activated via the kernel mode flag) Even if you're using a non-official compiler, linking against an object file built with clang's C++ compiler at the last stage should work fine for wrapping any other C++ APIs.

SQLite function calls all have invalid arguments

I'm trying to add the SQLite Amalgamation to my project. According to their page, I "Just copy the amalgamation into your source directory and compile it along with the other C code files in your project." I've also copied in sqlite3.h so I have access to the API.
However, any function call to the API, for instance:
sqlite3 *db;
int rc;
rc = sqlite3_open("test.db", &db);
results in the following error:
Invalid arguments '
Candidates are:
int sqlite3_open(const char *, * *) '
DataSettings.cpp
/FCS/src
line 24
Semantic Error
What am I doing wrong here? What have I neglected to set up?
The problem has the hallmarks of a name-mangling mismatch. Because C++ allows functions to be overloaded based on their argument types, C++ compilers must "mangle" function names they emit into object code to encode the argument types. C compilers do not do this, and do not expect it to be done to them. Specifying to a C++ compiler that a function has "C" linkage disables name mangling AND overloading of that function name; this is what extern "C" does.
Although C is similar in many ways to a subset of C++, the two are distinct languages. It is best to compile C code with a C compiler. One of your alternatives, therefore, is to build the C source of the sqlite amalgamation separately from your C++ code, into a library for instance, and link that with your C++ object files to produce the final executable.

How to Bypass a Standard C++ Function While Maintaining Its Functionality

I am looking for a way to be able to redefine a set of POSIX functions but then end the redefinition with a call to the original function. The idea is that I am trying to create a layer that can restrict what OS API's can be called depending on which "profile" is active. This "profile" determines what set of functions are allowed and any not specified should not be used.
For example, if in one profile I am not allowed to use strcpy, I would like to be able to either cause a compile time error (via static_assert) or print something to the screen saying "strcpy is not allowed in this profile" such as below:
MY_string.h
#include <string.h>
char *strcpy(char *restrict s1, const char *restrict s2)
{
#if defined(PROFILE_PASS_THROUGH)
printf("strcpy is not allowed in this profile\n");
return strcpy(s1, s2);
#elif defined(PROFILE_ERROR)
static_assesrt(0, "strcpy is not allowed in this profile\n");
return 0;
#else
return strcpy(s1, s2);
#endif
}
So that way within main.cpp I can use MY_string.h
#define PROFILE_PASS_THROUGH
#include "MY_string.h"
int main()
{
char temp1[10];
char temp2[10];
sprintf(temp2, "Testing");
if (0 = strcpy(temp1, temp2))
{
printf("temp1 is %s\n", temp1);
}
return 0;
}
Now I realize that the code I have written above will not compile properly due to the redefinition of strcpy, but is there a way to allow this sort of functionality without playing around with macros or creating my own standard c and c++ libraries?
You can write a preprocessor that changes calls to the standard routine to calls to your own routine. Such a preprocessor might be complicated, depending whether you need to recognize the full C++ grammar to distinguish calls using name spaces and so on or you can get away with more casual recognition of the calls.
You can link with your own library, producing a relocatable object module with resolved names stripped. Your library would contain routines with the standard names, such as strcpy, that execute whatever code you desire and call other names, such as Mystrcpy. The object module produced by this is then linked with a second library and with the standard library. The second library contains routines with those names, such as Mystrcpy, that call the original library names strcpy. The details for doing this are of course dependent on your linker. The goal is to have a chain like this: Original code calls strcpy. This is resolved to the version of strcpy in the first library. That version calls Mystrcpy. Mystrcpy calls the standard library strcpy.
You can compile to assembly and edit the names in the assembly so that your routines are called instead of the standard library routines.
On some systems, you can use dlsym and other functions defined in <dlfcn.h> to load the dynamic library that contains the standard implementations and to call them via pointers returned by dlsym instead of by the usual names in source code.
The GCC linker has a --wrap switch that resolves calls to foo to your routine __wrap_foo and resolves calls to __real_foo (which you would use in your implementation) to the real foo.
See also Intercepting Arbitrary Functions on Windows, UNIX, and Macintosh OS X Platforms.
No, cannot be done in C++. What you want is more akin to a LISP (or derivative) language, where you can grab the slot for an existing function and 'override it in place', potentially punting back to the original implementation.
Typical way of doing is on Unix is via LD_PRELOAD, example (Unix) below proxies a function call, malloc in particular (full example):
/**
* malloc() direct call
*/
inline void * libc_malloc(size_t size)
{
typedef void* (*malloc_func_t)(size_t);
static malloc_func_t malloc_func = (malloc_func_t) dlsym(RTLD_NEXT, "malloc");
return malloc_func(size);
}
In your MY_String.h:
... blah blah
using mynamespace::strcpy;
#endif // header guard or maybe not there if using pragma
then all strcpys that are not prefixed with std:: will use yours. If you REALLY want to ban them, grep and take a shotgun with you when you find the person who used it.
If using some recent GCC (e.g. version 4.7 or newer) you could also write a GCC plugin or a GCC extension in MELT to replace every call to strcpy to your own mystrcpy. This probably will take you some work (perhaps days, not hours) but has the enormous advantage to work inside the compiler, on the GCC compiler's internal representations (Gimple). So it will be done even after inlining, etc. And since you extend the compiler, you can tailor its behavior to what you want.
MELT is a domain specific language to extend GCC. It is designed for such tasks.
You cannot avoid these functions to be called.
A C++ program can do anything it wants, it could have some code that loads the strcpy symbol from libc and runs it. If a malicious developer want to call that function, you have no way to avoid it. To do that you'd need to run the C++ code in some special environment (in a sandbox, or virtual machine), but I'm afraid such technology is not available.
If you trust the developers, and you're just looking for a way to remind them not to call certain functions, then there could be some solution.
One solution could be avoiding to #include libc headers (like cstring), and only include your own header files where you only declared the desired functions.
Another solution could be that of looking to the compiled executable in order to find out what functions are called, or to LD_PRELOAD a library that redefines (and thus overrides) standard functions to make them print a warning at runtime.
Here is how you would you change MY_string.h
#include <cstring>
namespace my_functions{
char *strcpy(char *s1, const char *s2)
{
#if defined(PROFILE_PASS_THROUGH)
printf("strcpy is not allowed in this profile\n");
return std::strcpy(s1, s2);
#elif defined(PROFILE_ERROR)
static_assert(0, "strcpy is not allowed in this profile\n");
return 0;
#else
return std::strcpy(s1, s2);
#endif
}
}
using namespace my_functions;
For this to work you cannot include or have using namespace std;

How to incorporate C++ code in Objective-C project?

I'd like to use some C++ code in an Xcode project but I don't understand either language well enough yet to know how to proceed. I've been at the Obj-C for a while and have an app on the app store, but still learning...
The code I want to use has two files with the same name and .h and .c extensions. I would think they correspond to .h and .m files in Obj-C, but they lack the #interface and #implementation structure I'm familiar with. And there's a main.c that I don't know what to do with. It looks like it's the main program - should I try to pull its code out into my primary viewController?
Maybe a link to a good tutorial? Maybe this question's too vague...
FYI - the code I want to use is for calculating sunrise and sunset times, and is located at: http://www.risacher.org/sunwait/
Thanks!
EDIT:
Thanks for the suggestions - I will probably have to do some more learning before I get this. But I made some progress...
In main.c (seems weird to have a file called that...) there is a function(?) like this:
int mainFunction(int argc, char *argv[])
{
// a bunch of function-y stuff
}
It was called main but I changed it to mainFunction to get rid of an error. Now it compiles and I can call it but the compiler warns me thus: warning: implicit declaration of function 'mainFunction' and it crashes after I call it.
Now it compiles and I can call it but the compiler warns me thus: warning: implicit declaration of function 'mainFunction' and it crashes after I call it.
This is because, where you use this function, you do not forward-declare or include the declaration of the function. In your Objective-C code, you should add the following bit of code:
int mainFunction(int argc, char *argv[]);
Also note that the ".c" file extension is C code, not C++. Since Objective-C is a superset of C, you could just as easily change the extension to ".m", and you'd still get the same error since you need this forward declaration. I would strongly recommend familiarizing yourself with both C and C++ code before venturing into the world of Objective-C. If you wish to forgoe learning C++, then at the very least, you should strengthen your C knowledge before going into Objective-C, as the C fundamentals apply.
First of all, if your files have a .c extension, they are almost certainly C and not C++. All you have to do is add them to the project and target and include the relevant .h file in the Objective-C where you call the C functions.
Now the fact that you used to have a function called main() tells us that you had a stand alone program. Every stand alone program has to have a function called main(), it's the entry point for the program. Your Objective-C application will have a function main() already which is why you were getting an error. You can take the approach of renaming the duplicate and calling it but there are a number of pitfalls with that approach.
As you found out, you need a function prototype to stop the implicit declaration warning. This should be
int mainFunction(int argc, char* argv[]);
and should be in a header that you include in the .m file where you want to call it.
In C, certain assumptions are made about the parameters. argc is the number of char*s in argv. argv[0] is conventionally the name of the program as invoked on the command line. So argc must be at least 1 and argv[0] must point to a string. The remaining char*s in argv point to the command line parameters.
Typically, a command line program expects to be able to accept input from the keyboard and display output on the screen. This is done through three file descriptors: stdin, stdout and stderr. Stdin is for input, stdout is for normal output and stderr is for output of error and other 'out of band' messages. Intercepting these file descriptors in a GUI application is non trivial.
I suggest you work through the basics of C to gain an understanding of it. You can probably learn enough to progress your project in a day or two. The classic text is The C Programming Language. It's still one of the best IMHO.
There is a chapter in the Objective-C 2.0 guide here:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCPlusPlus.html#//apple_ref/doc/uid/TP30001163-CH10-SW1
Basically you can mix C++ and objective-C, but there are a couple of pitfalls. It sounds like you may need to learn more about C++ in general before you explore the nuances of objective-C++
Rename sources from .m to .mm, then they become Objective C++. You can instantiate and call C++ classes from Objective C code and vice versa. You cannot, though, derive ObjC classes from C++ classes and vice versa. Also, mind the calling conventions - the global functions in .m files are extern "C" as far as .mm/.cpp files are concerned.
Linking together .mm and .cpp works fine, too.
There are not many tutorials about this unfortunately. I think this has been asked a couple of times in stackoverflow, so searching here will give you some hints. The first pitfall you would want to avoid is, you need to use the ".mm" extension for your obj-c files to enable the c++ extension.
http://www.cocoadev.com/index.pl?CPlusPlusInCocoa
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCPlusPlus.html
Adding C++ Object to Objective-C Class
http://robnapier.net/blog/wrapping-c-objc-20
One last pointer is, look at opensource projects e.g. chrome to see how they mix up obj-c and C++. Google search is also your friend :).

How to call a JNI DLL from C++

I have a task to interface with a dll from a third party company using C++.
The dll package comes with:
the dll itself
a sample Java implementation - consists of a java wrapper(library) generated using the SWIG tool and the the java source file
documentation that states all the public datatypes, enumeration and member functions.
My other colleague is using Java(based on the example in package) to interface with the dll while I'm asked to use C++. The Java example looks straight forward... just import the wrapper and instantiate any class described in the docs..
More info on the dll:
From the docs, it says the dll was programmed using C++
From a hexdump, it shows that it was compiled using VC90 (VS C++ 2008 right?) and something from Dinkumware.
From a depends.exe output, the functions seems to be wrapped under JNI. For example: _Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect#20
My dilemma:
The dll company is not changing anything in the dll and not providing any other info.
How do i use the member functions in the class from the dll?
I did some simple LoadLibrary() and GetProcAddress and manage to get the address of the public member functions.
But i dunno how to use the functions that has the datatype parameters defined in the dll. For example:
From the docs, the member function is defined as:
void Server::connect(const StringArray, const KeyValueMap) throw(std::invalid_argument,std::out_of_range)
typedef std::map Server::KeyValueMap
typedef std::vector Server::StringArray
how do i call that function in C++. The std::map and std::vector in my compiler (VS 2005) has different functions listing that the one in the dll. For example, from the depends.exe output:
std::map // KeyValueMap - del, empty, get, has_1key,set
std::vector // StringArray - add, capacity, clear, get, isEMPTY, reserve, set, size
Any advice/strategy on how i should solve this? Is it possible to simply instantiate the class like the Java example?
If you are trying to use VS 2005 to try and interface with a DLL that is built using VS2008, your attempts will be mostly doomed unless you can use a plain C interface. Given your description, this is not the case; The runtime libraries differ between VS2005 and VS2008 so there is little chance that the object layout has stayed the same between compilers. The 'something from Dinkumware' that you're referring to is most likely the C++ standard library as ISTR that Microsoft uses the Dinkumware one.
With your above example you're also missing several important pieces of information - the types you describe (Server::StringArray and Server::KeyValueMap) are standard library containers. OK fine, but standard library containers of what? These containers are templates and unless you know the exact types these templates have been instantiated with, you're a little stuck.
Is this DLL intended to be called from C++ at all? The fact that it export a JNI interface suggests that it might not be in the first place. Does it export any other public symbols apart from those that are of the format _Java_...?
Of course if there is no other way in and you must use C++ instead of Java, you might want to look into embedding a JVM into your C++ app and use that to call through to the C++ dll. It's not what I'd call an elegant solution but it might well work.
I don't quite understand the use of C++ standard library data types here. How can Java code provide a std::map argument? Are the arguments you pass in always just "opaque" values you would get as output from a previous call to the library? That's the only way you're going to be able to make it work from code under a different runtime.
Anyway...
When you make a JNI module, you run javah.exe and it generates a header file with declarations like:
JNIEXPORT void JNICALL Java_Native_HelloWorld(JNIEnv *, jobject);
Do you have any such header file for the module?
These symbols are exported as extern "C" if I recall correctly, so if you can get the correct signatures, you should have no issues with name mangling or incompatible memory allocators, etc..
The "#20" at the end of the method signature means that the function is declared "stdcall" and that 20 bytes are put on the stack when the function is called. All these methods should start with a JNIEnv* and a jobject, these will total 8 bytes I believe, on a 32-bit environment, so that leaves 12 bytes of parameters you will need to know in order to generate a correct function prototype.
Once you figure out what the parameters are, you can generate something like this:
typedef void (__stdcall *X)(JNIEnv *, jobject, jint i, jboolean b);
Then, you can cast the result of GetProcAddress to an X and call it from your C++ code.
X x = (X)GetProcAddress(module, "name");
if (x) x(params...);
Unfortunately, what you have doesn't quite look like what I have seen in the past. I am used to having to deal with Java data types from C/C++ code, but it looks like this module is dealing with C++ data types in Java code, so I don't know how relevant any of my experience is. Hopefully this is some help, at least.