1

编辑:如果您要处理 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, &currentMessageSize);
    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  */

这两天我一直在挠头。如果有人知道该怎么做或可以指出我的方向,我会很难过。此外,如果您对我如何改进这篇文章有任何意见,我很想听听他们的意见,这对这个帖子有点新。通常我能够在网络上已经包含的大量知识库中找到答案。

4

1 回答 1

1

尝试通过将以下内容放在头文件顶部附近来显式指定外部 C 链接:

#ifdef __cplusplus
extern "C" {
#endif

这在底部附近:

#ifdef __cplusplus
}
#endif
于 2012-08-01T21:25:03.043 回答