通用头部占位符指针与实现中的转换 - 一个好主意?

时间:2014-12-15 16:51:06

标签: c casting

我正在构建一个小型多平台C库。设计目标是拥有一组适当通用的头文件,并为结构定义了许多占位符指针 - 如果这是正确的术语 - 就像这样:

/* mylib_types.h */

typedef struct _mylib_matrix *mylib_matrix;

这些占位符可用于在其他标题中指定函数原型的参数,例如:

/* mylib_api.h */

MY_API mylib_status mylibAddMatrix(mylib_matrix a,
                                   mylib_matrix b, 
                                   mylib_matrix* result);

所以,这对标题来说很好 - 一切都是独立的和独立的。然后,当涉及到实现库时,我想使用不同的底层,特定于平台的库来实际实现这些方法。

这个想法是库已经针对任何给定的平台进行了优化,但是库的API将被普遍定义(很容易交叉编译)。

我遇到的问题是:是的 - 我有这个工作 - 但是使用铸造的方式相当粗糙。我只是想知道最佳实践 - 如果有的话 - 实际上是什么?

例如,在我的方法实现中,我必须记住立即将占位符指针强制转换为我们用于该平台实现的实际类型的东西,并类似地抛弃任何结果。

e.g。

/* mylib_matrix.c */

#include “mylib_types.h"
#include “mylib_api.h”

#include <PlatformSpecificFunkyMatrix.h>

MY_API mylib_status mylibAddMatrix(mylib_matrix a,
                                   mylib_matrix b, 
                                   mylib_matrix* result)
{
    *result = (mylib_matrix)PlatformSpecificFunkyMatrix_AddMatrix(
        (PlatformSpecificFunkyMatrix*)a, 
        (PlatformSpecificFunkyMatrix*)b);

    return MYLIB_SUCCESS;
}

这一切似乎非常脆弱,并且我有责任忘记演员或允许编译器进行任何类型检查。它完全有原则吗?

我想我可以在我的演员类型中明确表达 - 但仍需要一些考虑。也许一些预处理器#defines可能会帮助完成任务,但当然可能会变得相当混乱......我当然可以为每个实现重新定义低级结构(例如mylib_matrix),但后来我们正在谈论一个每个平台的不同标头集(同样,我可以使用预处理器来帮助交换正确的定义)。

嗯。也许我在这方面做得太多......

1 个答案:

答案 0 :(得分:2)

绕过施法的一种方法。

在平台特定文件中,使用:

struct _mylib_matrix
{
   PlatformSpecificFunkyMatrix* realMatrix;
};

MY_API mylib_status mylibAddMatrix(mylib_matrix a,
                                   mylib_matrix b, 
                                   mylib_matix* result)
{
    PlatformSpecificFunkyMatrix* r = 
       PlatformSpecificFunkyMatrix_AddMatrix(a->realMatrix, b->realMatrix);

    *result = malloc(sizeof(_mylib_matrix));
    *result->realMatrix = r

    return MYLIB_SUCCESS;
}

更好......

您可以使用以下方法避免双重间接和投射需求:

struct _mylib_matrix
{
   // Add all the data here that you have in PlatformSpecificFunkyMatrix
};

typedef struct _mylib_matrix PlatformSpecificFunkyMatrix;

然后,

MY_API mylib_status mylibAddMatrix(mylib_matrix a,
                                   mylib_matrix b, 
                                   mylib_matix* result)
{
    *result = PlatformSpecificFunkyMatrix_AddMatrix(a, b);    
    return MYLIB_SUCCESS;
}