如何组合两个仅在声明的类型上不同的函数

How can I combine two functions that differ only in the types declared

本文关键字:声明 类型 函数 两个 何组合 组合      更新时间:2023-10-16

我正在编写一个 mex 函数来从 FLI 相机抓取图像。图像可以具有不同的位深度(8 位或 16 位),因此我不得不编写两个函数,它们仅在声明的类型上有所不同。我的问题:如何组合以下功能以消除尽可能多的代码重复?

mxArray* grabFrame16Bit(flidev_t device, long imageWidth, long imageHeight) {
    long imageSize = imageWidth*imageHeight;
    uint16_t *image = (uint16_t *) mxCalloc(imageSize, sizeof(uint16_t));
    int iRow, ind;
    for (iRow = 0; iRow < imageHeight; iRow++) {
        ind = iRow*imageWidth;
        fli::checkReturn(FLIGrabRow(device, image+ind, imageWidth),
                         "fliTestSnapMex:FLIGrabRow"); 
    }
    mxArray *outMat = mxCreateDoubleMatrix(imageWidth, imageHeight, mxREAL);
    double *imageOut = mxGetPr(outMat);
    int i;
    for (i = 0; i < imageSize; i++)
        imageOut[i] = (double) image[i];
    mxFree(image);
    image = NULL;
    return outMat;
}
mxArray* grabFrame8Bit(flidev_t device, long imageWidth, long imageHeight) {
    long imageSize = imageWidth*imageHeight;
    uint8_t *image = (uint8_t *) mxCalloc(imageSize, sizeof(uint8_t));
    int iRow, ind;
    for (iRow = 0; iRow < imageHeight; iRow++) {
        ind = iRow*imageWidth;
        fli::checkReturn(FLIGrabRow(device, image+ind, imageWidth),
                         "fliTestSnapMex:FLIGrabRow"); }
    mxArray *outMat = mxCreateDoubleMatrix(imageWidth, imageHeight, mxREAL);
    double *imageOut = mxGetPr(outMat);
    int i;
    for (i = 0; i < imageSize; i++)
        imageOut[i] = (double) image[i];
    mxFree(image);
    image = NULL;
    return outMat;
}

这里声明了我编写的一个自定义函数以及其他 API 函数,以防您不熟悉 FLI API 或 MATLAB mex/mx API。

// allocates memory
void *mxCalloc(mwSize n, mwSize size);
// checks for an error
void fli::checkReturn(long returnCode, char * errorId); 
// grabs a row of the image
long FLIGrabRow(flidev_t device, void * buffer, size_t width); 
// creates a double matrix
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity complexFlag); 
// gives a pointer to the data in the matrix
double *mxGetPr(const mxArray *pm); 

欢迎来到模板的世界!

一种天真的方法是只替换一个类型的所有匹配项,并将其替换为模板类型参数。

template <class T>
mxArray* grabFrame(flidev_t device, long imageWidth, long imageHeight) {
    long imageSize = imageWidth*imageHeight;
    T *image = (T*) mxCalloc(imageSize, sizeof(T));
    int iRow, ind;
    for (iRow = 0; iRow < imageHeight; iRow++) {
        ind = iRow*imageWidth;
        fli::checkReturn(FLIGrabRow(device, image+ind, imageWidth),
                         "fliTestSnapMex:FLIGrabRow"); 
    }
    mxArray *outMat = mxCreateDoubleMatrix(imageWidth, imageHeight, mxREAL);
    double *imageOut = mxGetPr(outMat[0]);
    int i;
    for (i = 0; i < imageSize; i++)
        imageOut[i] = (double) image[i];
    mxFree(image);
    image = NULL;
    return outMat;
}

由于模板参数的类型无法从函数参数中推断出来,因此必须在每次调用时显式指定它:

mxArray* array = grabFrame<uint8_t>(device, width, height);

编辑:你的代码没有 return 语句,所以我允许自己添加它。

template<typename PixelType>
mxArray* grabFrame(flidev_t device, long imageWidth, long imageHeight) {
    long imageSize = imageWidth*imageHeight;
    PixelType *image = (PixelType *) mxCalloc(imageSize, sizeof(PixelType));
    int iRow, ind;
    for (iRow = 0; iRow < imageHeight; iRow++) {
        ind = iRow*imageWidth;
        fli::checkReturn(FLIGrabRow(device, image+ind, imageWidth),
                     "fliTestSnapMex:FLIGrabRow"); 
    }
    mxArray *outMat = mxCreateDoubleMatrix(imageWidth, imageHeight, mxREAL);
    double *imageOut = mxGetPr(outMat[0]);
    int i;
    for (i = 0; i < imageSize; i++)
        imageOut[i] = (double) image[i];
    mxFree(image);
    image = NULL;
}

电话会议

 grabFrame<uint8_t>(....)

 grabFrame<uint16_t>(...)