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_IN开发者_StackOverflow中文版VALID_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.)
精彩评论