включить заголовок c ++ (fstream) из кода на основе c? - PullRequest
3 голосов
/ 05 января 2011

Я изменяю открытый исходный код (pngcrush) и хочу включить заголовок c ++ (fstream, iostream)

Подача жалоб на то, что таких файлов нет.
Как мне их включить?

Спасибо

-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

по коду

uLong ZEXPORT adler32(adler, buf, len)
    uLong adler;
    const Bytef *buf;
    uInt len;
{   
    unsigned long sum2;
    unsigned n;
  • второе редактирование -

Я закончил скомпилировать его как код c (используя gcc), но с #ifdef __cplusplus extern "C" {} #endif .. Я поставил этот #ifdef после других кодов c проектов.

Теперь он компилируется, но с предупреждением (у ranlib нет символов, я гуглил его, похоже, это происходит только в 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

также, когда я связываю этот libpngcrush.а в моем коде c ++,
он умирает, когда я впервые вызываю функцию, находящуюся в библиотеке.

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

Похоже, я даже не могу добраться до первой строки вызванной функции.

Ответы [ 4 ]

5 голосов
/ 05 января 2011

Вы не можете.Исходный код C ++ нельзя использовать из C.

Единственный способ - это переключиться на C ++: преобразовать ваш код C в C ++ (для этого часто не требуется никаких или незначительных изменений в коде, только в сценарии сборки, чтобывключите компилятор), а затем используйте заголовок и инструменты C ++.


РЕДАКТИРОВАТЬ:

C ++ использует другой способ, чем C, чтобы идентифицировать символы (функции, переменные и прочее)).

uLong ZEXPORT adler32(adler, buf, len) просто вызывается C adler32, тогда как в C ++ он может называться _Z7adler32lPKci.Это необходимо для обеспечения перегрузки.

Если вы хотите, чтобы компилятор дал ему то же самое имя , которое дает C, вы можете поместить объявление в extern "C":

extern "C"
{
    uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len);
}
3 голосов
/ 05 января 2011

Я бы советовал против этого. Если проект написан на C, сохраните его на C и используйте FILE *, printf и т. Д.

Однако есть разница, если вы интегрируете C ++ с C и хотите либо: написать модуль на C ++, но дать ему интерфейс C - написать модуль на C ++ и вызвать интерфейс C.

Хотя вы можете открыть fstream для C, предоставив iostream интерфейс C, я не вижу большого преимущества в этом. Например, нельзя перегружать функции потоковой передачи (т. Е. Использовать одно и то же имя с печатью разных типов).

Для вашего собственного кода, хотя в вашей собственной библиотеке, вы можете написать на C ++ и дать ему интерфейс на C. В таком случае вы используете предварительные объявления ваших классов (вызывая их struct) и free-функции, которые обращаются к нему с помощью указателей, конечно, поскольку C не имеет ссылок.

Пользователи всегда имеют дело с указателями на ваш класс, и, конечно, им нужна функция, чтобы избавиться от них (они не просто звонят бесплатно).

2 голосов
/ 05 января 2011

ваш код C будет скомпилирован с помощью компилятора C, который не распознает такие вещи, как класс, шаблон, новый, удаление и т. Д., Поэтому невозможно использовать библиотеку C ++ из C

Скорее всего, вы также столкнетесь с ошибками, если попытаетесь скомпилировать код на C как C ++ из-за более строгой системы типов. Кроме того, ваши коллеги могут не ценить ваше преобразование модуля C в C ++.

попытаться достичь своей цели, используя C file io и C streams; ФАЙЛ, fopen, fread, fwrite, fprintf, stdout, stderr и т. Д.

1 голос
/ 05 января 2011

Ты не.Если код C, вы не можете просто добавить заголовки C ++ и ожидать, что он будет работать.C и C ++ - это два различных языка в целом.

Вместо этого перейдите к созданию всего компонента в C ++, что может повлечь за собой незначительные изменения в базе кода, в зависимости от того, как она написана.

(Это не рекомендация; это единственный способ, которым вы сможете использовать эти заголовки. Вместо этого, если он написан на C, придерживайтесь C. Тогда он останется поддерживаемым с оригинальнымкодовая.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...