Utilice C++
Desde chistes no parecen ser permitidos aquí es la versión C puro. Como señaló otro comentarista si realmente desea proteger su interior de los usuarios de su Api, ha visto y usado muchos de estos Apis. Estas Apis son, p. el modo de usuario de Windows o Linux Apis. Ahí creas objetos kernel a los que nunca tendrás acceso. Los Apis para tratar con objetos kernel usan una construcción sintética llamada handle que no es simplemente un puntero a su propio objeto, sino que es un índice de una matriz donde el kernel ha almacenado los metadatos relevantes para su objeto. Puede usar la misma idea para su Apis también. Aquí, por ejemplo, es una API pública C-Style:
// Public.h
#include <stdlib.h>
typedef enum
{
None = 0,
PointType = 1
} Types;
typedef int Handle;
Handle CreateType(Types type);
int DeleteType(Handle object);
void IncrementX(Handle point);
void PrintPoint(Handle point);
Como se puede ver que tiene métodos genéricos que crean y eliminan los objetos que se definen aquí en una enumeración. Los métodos que usan el objeto necesitarán buscar el manejador de enteros para obtener el objeto de metadatos donde se almacenan los datos reales. Este diseño no es muy eficiente si los objetos que administra son pequeños ya que para cada objeto se necesita un segundo objeto que almacena el tipo de objeto, el valor de manejo y el puntero a los datos reales. pero se obtiene mucho más fuertes garantías de seguridad tales como
- seguridad Tipo
- identificadores no válidos son fáciles de encontrar
- Doble libre es imposible ya que se puede administrar el estado libre en el meta objeto
Un uso típico de la Api podría tener este aspecto:
Handle h = CreateType(PointType);
IncrementX(h);
IncrementX(h);
PrintPoint(h);
DeleteType(h);
Un y hay una implementación súper secreta en privado.CPP, donde la matriz de búsqueda de la manija y algunos métodos de ayuda existir:
// Private.C
#include "stdafx.h"
#include <stdlib.h>
#include <Windows.h> // for ZeroMemory
#include "Public.h"
typedef struct
{
LPVOID pData;
Types type;
Handle handle;
} HandleInfo;
typedef struct
{
int x;
int y;
} Point;
HandleInfo *pAllocated;
int HandleBuffer = 0xffff;
unsigned char bInit = 0;
HandleInfo *GetFreeHandle()
{
int i;
if(!bInit)
{
pAllocated = (HandleInfo *) malloc(sizeof(HandleInfo)*HandleBuffer);
bInit = 1;
ZeroMemory(pAllocated, sizeof(HandleInfo)*HandleBuffer);
}
for(i=0; i<HandleBuffer; i++)
{
HandleInfo *pInfo = (pAllocated+i);
if(0 == pInfo->handle )
{
pInfo->handle = i+1;
return pInfo;
}
}
return NULL;
}
HandleInfo * GetHandleInfo(Handle h)
{
if(h <= 0 || h >= HandleBuffer-1)
{
return NULL;
}
return (pAllocated+h-1);
}
Handle CreateType(Types typeId)
{
HandleInfo *pInfo;
pInfo = GetFreeHandle();
if(NULL == pInfo)
{
return -1;
}
pInfo->type = typeId;
switch(typeId)
{
case PointType:
pInfo->pData = malloc(sizeof(Point));
ZeroMemory(pInfo->pData, sizeof(Point));
break;
}
return pInfo->handle;
}
int DeleteType(Handle object)
{
HandleInfo *pInfo = GetHandleInfo(object);
if(NULL == pInfo )
{
return -1;
}
if(pInfo->handle != 0)
{
free(pInfo->pData);
pInfo->pData = NULL;
pInfo->handle = 0;
return 1;
}
else
{
return 0; // Handle was already closed
}
}
void *GetObjectOfCorrectType(Handle object, Types type)
{
HandleInfo *p = GetHandleInfo(object);
if(p == NULL)
{
return NULL;
}
if(p->type != type)
{
return NULL; // handle has wrong object type
}
return p->pData;
}
void IncrementX(Handle point)
{
Point *pPoint = (Point *) GetObjectOfCorrectType(point, PointType);
if(pPoint == NULL)
{
return;
}
pPoint->x++;
}
void PrintPoint(Handle point)
{
Point *pPoint = (Point *) GetObjectOfCorrectType(point, PointType);
if(pPoint == NULL)
{
return;
}
printf("Point has x: %d y: %d", pPoint->x, pPoint->y);
}
Suyo, Alois Kraus
Se puede crear un 'something_protected.h' y declarar su material protegido por allí, e incluirlo formar su' .c' archivo así como su archivo "público" '.h'. - Aunque no creo que sea la convención para este problema. Si necesita protección use C++, tiene funciones más avanzadas para cosas como esta. – vbence
Lo que "falta" es la etiqueta struct. Después de su código anterior, hay una definición de estructura sin nombre en el alcance: no puede referirse a ella con 'struct something'; debe referirse a él por su nombre de tipo 'punto'. – pmg