Вызываете пользовательскую бесплатную подпрограмму C из деструктора C ++? - PullRequest
1 голос
/ 18 января 2012

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

Мой код для myArchive имеет класс Archive, который содержит закрытую переменную md типа Metadata *, определенную в моей библиотеке C.

Вот заголовок myArchive.hpp:

#ifndef MYARCHIVE_H
#define MYARCHIVE_H

#include "myLibraryHeaders.h"
...
namespace Archive {
    class Archive {
        public:
            Archive();
            virtual ~Archive();

            Metadata * getMd() { return md; }
            Metadata ** getMdRef() { return &md; }
            void setMd(Metadata *_md) { md = _md; }
        private:
            Metadata *md;
    };

    Archive::Archive() {
        md = NULL;
    }

    Archive::~Archive() {
        if (md != NULL) 
           freeMetadata(&md);
    }
}

#endif

Функция freeMetadata() просто освобождает элементы в связанном списке:

void freeMetadata(Metadata **md) {                                                                                                                                                                                                         
    Metadata *iter;
    Metadata *prev = NULL;

    if (! *md)
        return;

    for (iter = *md; iter != NULL; iter = iter->next) {
        /* ... */
        if (prev != NULL)
            free(prev);
        prev = iter;
    } 

    if (prev != NULL) {
        free(prev);
        prev = NULL;
    }
}

Вот объявление в одном из заголовков, на которое есть ссылка в myLibraryHeaders.h:

#ifdef __cplusplus
extern "C" {
#endif

#ifndef METADATAHELPERS_H
#define METADATAHELPERS_H

typedef struct metadata {
    /* ... */
    struct metadata *next;
} Metadata;

/* ... */
void freeMetadata(Metadata **md);
/* ... */

#endif

#ifdef __cplusplus
}
#endif

У меня есть другие переменные, но это вопрос, относящийся к моему вопросу:

Когда я пытаюсь скомпилировать это, я получаю ошибку за пределами области действия:

...
g++ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1 -DUSE_ZLIB -DUSE_BZLIB -O3 -Wformat -Wall -Wswitch-enum -static -c myArchive.cpp -o myArchive.o
myArchive.hpp: In destructor "virtual myArchive::Archive::~Archive()":
myArchive.hpp:87: error: "freeMetadata" was not declared in this scope                                                                                                                                                  
make: *** [myArchive] Error 1

Но я включаю заголовочный файл (в myLibraryHeaders.h), который объявляет freeMetadata(). Кроме того, компилятор не жалуется на тип Metadata, который также определен в одном из заголовков в myLibraryHeaders.h.

Что я пропускаю или делаю неправильно?

1 Ответ

0 голосов
/ 18 января 2012

Единственное объяснение, которое имеет смысл, заключается в том, что вы каким-то образом получаете METADATAHELPERS_H, определенный до включения myLibraryHelpers.h, вероятно, из-за некоторого предварительного включения где-то - какой-то циклической зависимости включения. Вы можете попытаться использовать g++ -E для извлечения пост-предварительно обработанного текста и попытаться выяснить, можете ли вы распутать проблему из этого (найдите, где в этом появляется freeMetaData, чтобы получить некоторое представление о порядке, в котором вы оказались), но в целом решение этих проблем может быть сложным

...