编辑:如果您要处理 GRIB 文件,我会推荐由Open Source Geospatial Foundation支持的GDAL 库。你会省去很多麻烦:)
我在 Ubuntu 中使用 Qt creator 创建一个 c++ 应用程序。我正在尝试使用具有标头 grib2.h 的外部库 libgrib2c.a。一切都可以编译,但是当它尝试链接时出现错误:
未定义对'seekgb(_IO_FILE*, long, long, long*, long*) 的引用
我尝试用以下方法包装头文件:
extern "C"{
#include "grib2.h"
}
但它没有解决任何问题,所以我认为这不是我的问题。在 .pro 文件中,我有一行:
include($${ROOT}/Shared/common/commonLibs.pri)
在 commonLibs.pri 我有:
INCLUDEPATH+=$${ROOT}/external_libs/g2clib/include
LIBS+=-L$${ROOT}/external_libs/g2clib/lib
LIBS+=-lgrib2c
我没有遇到查找库的错误。如果我在 libgrib2c.a 上执行 nm 命令,我会得到:
nm libgrib2c.a | grep seekgb
seekgb.o:
00000000 T seekgb
当我使用 LIBS+=-Wl,--verbose 的附加参数运行 qmake 时,我可以在输出中找到 lib 文件:
attempt to open /usr/lib/libgrib2c.so failed
attempt to open /usr/lib/libgrib2c.a failed
attempt to open /mnt/sdb1/ESMF/App/ESMF_App/../external_libs/linux/qwt_6.0.2/lib/libgrib2c.so failed
attempt to open /mnt/sdb1/ESMF/App/ESMF_App/../external_libs/linux/qwt_6.0.2/lib/libgrib2c.a failed
attempt to open ..//Shared/Config/lib/libgrib2c.so failed
attempt to open ..//Shared/Config/lib/libgrib2c.a failed
attempt to open ..//external_libs/libssh2/lib/libgrib2c.so failed
attempt to open ..//external_libs/libssh2/lib/libgrib2c.a failed
attempt to open ..//external_libs/openssl/lib/libgrib2c.so failed
attempt to open ..//external_libs/openssl/lib/libgrib2c.a failed
attempt to open ..//external_libs/g2clib/lib/libgrib2c.so failed
attempt to open ..//external_libs/g2clib/lib/libgrib2c.a succeeded
虽然它没有显示库中的任何 .o 文件,但这是因为它是我的 c++ 应用程序中的 ac 库吗?
在我试图使用我拥有的库的 .cpp 文件中:
#include "gribreader.h"
#include <stdio.h>
#include <stdlib.h>
#include <external_libs/g2clib/include/grib2.h>
#include <Shared/logging/Logger.hpp>
//------------------------------------------------------------------------------
/// Opens a GRIB file from disk.
///
/// This function opens the grib file and searches through it for how many GRIB
/// messages are contained as well as their starting locations.
///
/// \param a_filePath. The path to the file to be opened.
/// \return True if successful, false if not.
//------------------------------------------------------------------------------
bool GRIBReader::OpenGRIB(std::string a_filePath)
{
LOG(notification)<<"Attempting to open grib file: "<< a_filePath;
if(isOpen())
{
CloseGRIB();
}
m_filePath = a_filePath;
m_filePtr = fopen(a_filePath.c_str(), "r");
if(m_filePtr == NULL)
{
LOG(error)<<"Unable to open file: " << a_filePath;
return false;
}
LOG(notification)<<"Successfully opened GRIB file";
g2int currentMessageSize(1);
g2int seekPosition(0);
g2int lengthToBeginningOfGrib(0);
g2int seekLength(32000);
int i(0);
int iterationLimit(300);
m_GRIBMessageLocations.clear();
m_GRIBMessageSizes.clear();
while(i < iterationLimit)
{
seekgb(m_filePtr, seekPosition, seekLength,
&lengthToBeginningOfGrib, ¤tMessageSize);
if(currentMessageSize != 0)
{
LOG(verbose) << "Adding GRIB message location " << lengthToBeginningOfGrib
<< " with length " << currentMessageSize;
m_GRIBMessageLocations.push_back(lengthToBeginningOfGrib);
m_GRIBMessageSizes.push_back(currentMessageSize);
seekPosition = lengthToBeginningOfGrib + currentMessageSize;
LOG(verbose) << "GRIB seek position moved to " << seekPosition;
}
else
{
LOG(notification)<<"End of GRIB file found, after "<< i
<< " GRIB messages.";
break;
}
}
if(i >= iterationLimit)
{
LOG(warning) << "The iteration limit of " << iterationLimit
<< "was reached while searching for GRIB messages";
}
return true;
}
头文件 grib2.h 如下:
#ifndef _grib2_H
#define _grib2_H
#include<stdio.h>
#define G2_VERSION "g2clib-1.4.0"
#ifdef __64BIT__
typedef int g2int;
typedef unsigned int g2intu;
#else
typedef long g2int;
typedef unsigned long g2intu;
#endif
typedef float g2float;
struct gtemplate {
g2int type; /* 3=Grid Defintion Template. */
/* 4=Product Defintion Template. */
/* 5=Data Representation Template. */
g2int num; /* template number. */
g2int maplen; /* number of entries in the static part */
/* of the template. */
g2int *map; /* num of octets of each entry in the */
/* static part of the template. */
g2int needext; /* indicates whether or not the template needs */
/* to be extended. */
g2int extlen; /* number of entries in the template extension. */
g2int *ext; /* num of octets of each entry in the extension */
/* part of the template. */
};
typedef struct gtemplate gtemplate;
struct gribfield {
g2int version,discipline;
g2int *idsect;
g2int idsectlen;
unsigned char *local;
g2int locallen;
g2int ifldnum;
g2int griddef,ngrdpts;
g2int numoct_opt,interp_opt,num_opt;
g2int *list_opt;
g2int igdtnum,igdtlen;
g2int *igdtmpl;
g2int ipdtnum,ipdtlen;
g2int *ipdtmpl;
g2int num_coord;
g2float *coord_list;
g2int ndpts,idrtnum,idrtlen;
g2int *idrtmpl;
g2int unpacked;
g2int expanded;
g2int ibmap;
g2int *bmap;
g2float *fld;
};
typedef struct gribfield gribfield;
/* Prototypes for unpacking API */
void seekgb(FILE *,g2int ,g2int ,g2int *,g2int *);
g2int g2_info(unsigned char *,g2int *,g2int *,g2int *,g2int *);
g2int g2_getfld(unsigned char *,g2int ,g2int ,g2int ,gribfield **);
void g2_free(gribfield *);
/* Prototypes for packing API */
g2int g2_create(unsigned char *,g2int *,g2int *);
g2int g2_addlocal(unsigned char *,unsigned char *,g2int );
g2int g2_addgrid(unsigned char *,g2int *,g2int *,g2int *,g2int );
g2int g2_addfield(unsigned char *,g2int ,g2int *,
g2float *,g2int ,g2int ,g2int *,
g2float *,g2int ,g2int ,g2int *);
g2int g2_gribend(unsigned char *);
/* Prototypes for supporting routines */
extern double int_power(double, g2int );
extern void mkieee(g2float *,g2int *,g2int);
void rdieee(g2int *,g2float *,g2int );
extern gtemplate *getpdstemplate(g2int);
extern gtemplate *extpdstemplate(g2int,g2int *);
extern gtemplate *getdrstemplate(g2int);
extern gtemplate *extdrstemplate(g2int,g2int *);
extern gtemplate *getgridtemplate(g2int);
extern gtemplate *extgridtemplate(g2int,g2int *);
extern void simpack(g2float *,g2int,g2int *,unsigned char *,g2int *);
extern void compack(g2float *,g2int,g2int,g2int *,unsigned char *,g2int *);
void misspack(g2float *,g2int ,g2int ,g2int *, unsigned char *, g2int *);
void gbit(unsigned char *,g2int *,g2int ,g2int );
void sbit(unsigned char *,g2int *,g2int ,g2int );
void gbits(unsigned char *,g2int *,g2int ,g2int ,g2int ,g2int );
void sbits(unsigned char *,g2int *,g2int ,g2int ,g2int ,g2int );
int pack_gp(g2int *, g2int *, g2int *,
g2int *, g2int *, g2int *, g2int *, g2int *,
g2int *, g2int *, g2int *, g2int *,
g2int *, g2int *, g2int *, g2int *, g2int *,
g2int *, g2int *, g2int *);
#endif /* _grib2_H */
这两天我一直在挠头。如果有人知道该怎么做或可以指出我的方向,我会很难过。此外,如果您对我如何改进这篇文章有任何意见,我很想听听他们的意见,这对这个帖子有点新。通常我能够在网络上已经包含的大量知识库中找到答案。