如何在多个 .c 文件中包含不透明类型?

How to include opaque type in multiple .c files?

我应该根据头文件和一些进一步的描述来制作一个程序。需要使用不透明类型的问题。不透明结构在头文件中与其他一些函数一起声明。但是每个函数都应该有自己的 .c 文件,问题来了。我应该做什么或者我应该在哪里定义不透明结构以便我的函数可以使用它?

我有这样的文件:

header.h source.c(主要) function1.c fuction2.c 等等

在这种情况下我不知道该怎么办。

我将创建一个私有(内部)header 文件,与 public header.h 文件分开,其中包含结构的定义。

为了保持一致性,它可能应该包括 public header。类似于:

#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 并访问结构成员。

您的全局 header 文件应该定义一个没有实现的类型名称,以及用于创建、销毁和处理该类型数据的函数原型。

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

然后你需要一个内部header,它提供结构的实现。

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

那么具有特定例程实现的文件将使用内部 header,因为它们需要知道结构细节才能访问它们。

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;
}

而外部模块将使用public header,因为它们只需要知道结构exists以及使用什么工具来处理它。

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);
    }
}