Как включить непрозрачный тип в несколько файлов .c? - PullRequest
0 голосов
/ 16 апреля 2019

Я должен сделать программу, основанную на заголовочном файле и некотором дополнительном описании.Необходима работа с непрозрачным типом.Непрозрачная структура объявлена ​​в заголовочном файле с некоторыми другими функциями.Но каждая функция должна иметь свой собственный файл .c, и здесь возникает вопрос.Что мне делать или где я должен определить непрозрачную структуру, чтобы мои функции могли с ней работать?

У меня есть файлы типа:

header.h source.c (main) function1.c fuction2.c и т. д.

И в этой ситуации я понятия не имею, что делать.

Ответы [ 2 ]

4 голосов
/ 16 апреля 2019

Я хотел бы создать частный (внутренний) заголовочный файл, отдельный от публичного файла header.h, который содержит определение структуры.

Для согласованности он, вероятно, должен включать публичный заголовок.Что-то вроде:

#ifndef INTERNAL_HEADER_H_
#define INTERNAL_HEADER_H_

#include "header.h"  // contains 'struct foo;'

struct foo {
    int data;  // or whatever
};

#endif

Тогда каждый из ваших .c файлов может включать в себя internal_header.h и получать доступ к членам структуры.

2 голосов
/ 16 апреля 2019

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

header.h

#ifndef HEADER_H_
#define HEADER_H_

struct XyzData;

typedef struct XyzData XYZDATA;
typedef struct XyzData *P_XYZDATA;

P_XYZDATA CreateEmptyXyzData();
P_XYZDATA CreateFilledXyzData(int param1, int param2);
void DestroyXyzData(P_XYZDATA pData);
int ModifyXyzData(P_XYZDATA pData, int action, int param);

#endif

Затем вам нужен внутренний заголовок, который обеспечивает реализацию для структуры.

xyzintheader.h

#ifndef XYZINTHEADER_H_
#define XYZINTHEADER_H_

#include "header.h"    // include the XyzData declaration

struct XyzData {       // and add its definition
    int   par1;
    int   par2;
};

#endif

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

xyzcreate.c

#include "xyzintheader.h"
#include <stdlib.h>

P_XYZDATA CreateEmptyXyzData() {
    return calloc(1, sizeof(XYZDATA));
};

xyzcreatf.c

#include "xyzintheader.h"
#include <stdlib.h>

P_XYZDATA CreateFilledXyzData(int param1, int param2) {
    if (P_XYZDATA pData = malloc(sizeof(XYZDATA))) {
        pData->par1 = param1;
        pData->par2 = param2;
        return pData;
    }
    return NULL;
};

xyzdestr.c

#include "xyzintheader.h"
#include <stdlib.h>

void DestroyXyzData(P_XYZDATA pData) {
    free(pData);
}

xyzmodif.c

#include "xyzintheader.h"

int ModifyXyzData(P_XYZDATA pData, int action, int param) {
    if (! pData)
        return -1;
    switch (action) {
    case 0:
        // do something
        pData->par1 = pData->par2 = 0;
        return 0;

    case 1:
        // do something
        pData->par1 += param;
        pData->par2 -= param;
        return 0;
    }

    return -2;
}

И внешние модули будут использовать открытый заголовок, потому что им нужно только знать структуру существует и какие инструменты использовать для ее обработки.

source.c

#include "header.h"

void SomeExternalLogic()
{
    if (P_XYZDATA pData = CreateEmptyXyzData()) {
        ModifyXyzData(pData, 0, 0);
        ModifyXyzData(pData, 1, 3);
        if (ModifyXyzData(pData, 13, 17) < 0)
            WriteSomeErrorMessage();

        DestroyXyzData(pData);
    }
}
...