簡體   English   中英

C:取消引用不完整類型錯誤的指針

[英]C: Dereferencing pointer to incomplete type error

我試圖在OS X上編譯的項目是: https : //github.com/Ramblurr/PietCreator

不幸的是,我無法通過以下內容解決問題:

width = info_ptr->width;
height = info_ptr->height;
ncol = 2 << (info_ptr->bit_depth - 1);

產生錯誤的地方:

file.c: In function ‘read_png’:
file.c:1117: error: dereferencing pointer to incomplete type
file.c:1118: error: dereferencing pointer to incomplete type
file.c:1119: error: dereferencing pointer to incomplete type

下面的read_png函數的完整代碼:

#include <png.h>
#include <math.h>

png_byte bit_depth;

png_structp png_ptr;
png_infop info_ptr;
int number_of_passes;
png_bytep * row_pointers;


int
read_png (char *fname)
{
  char header [8];

  FILE *in;
  int i, j, ncol, rc;

  if (! strcmp (fname, "-")) {
    /* read from stdin: */
    vprintf ("info: not trying to read png from stdin\n");
    return -1;
  }

  if (! (in = fopen (fname, "rb"))) { 
    fprintf (stderr, "cannot open `%s'; reason: %s\n", fname,
         strerror (errno));
    return -1;
  }

  if (! in || (rc = fread (header, 1, 8, in)) != 8
      || png_sig_cmp ((unsigned char *) header, 0, 8) != 0) {
    return -1;
  }

  if (! (png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0))
      || ! (info_ptr = png_create_info_struct (png_ptr))) {
    return -1;
  }

  png_init_io (png_ptr, in);
  png_set_sig_bytes (png_ptr, 8);

  png_read_png (png_ptr, info_ptr, 
        PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_STRIP_ALPHA
        | PNG_TRANSFORM_EXPAND, NULL);
  /**       | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_SHIFT **/

  row_pointers = png_get_rows (png_ptr, info_ptr);

  width = info_ptr->width;
  height = info_ptr->height;
  ncol = 2 << (info_ptr->bit_depth - 1);

  vprintf ("info: got %d x %d pixel with %d cols\n", width, height, ncol);

  alloc_cells (width, height);

  for (j = 0; j < height; j++) {
    png_byte *row = row_pointers [j];
    for (i = 0; i < width; i++) {

      png_byte *ptr = & row [i * 3];

      /* ncol always 256 ? */
      int r = (ptr [0] * 256) / ncol;
      int g = (ptr [1] * 256) / ncol;
      int b = (ptr [2] * 256) / ncol;

      int col = ((r * 256 + g) * 256) + b;
      int col_idx = get_color_idx (col);

      if (col_idx < 0) {
    if (unknown_color == -1) {
      fprintf (stderr, "cannot read from `%s'; reason: invalid color found\n",
           fname);
      return -1;
    } else {
      /* set to black or white: */
      col_idx = (unknown_color == 0 ? c_black : c_white);
    }
      }

      set_cell (i, j, col_idx);
    }
  }

  return 0;
}

我認為這是由png.h模塊的創建者設計的。

應該將png_infop聲明為指向 "png.h" 的結構指針 實際的結構聲明和定義應位於"png.c"

作者不想公開該struct的內部struct因此該struct"png.c"定義。

這意味着您無法訪問該結構的任何成員(即: info_ptr->widthinfo_ptr->heightinfo_ptr->bit_depth

struct成員並不意味着用戶可以訪問。

我敢打賭,如果作者認為您將需要widthheightbit_depth信息(例如: getWidth(info_ptr)getHeight(info_ptr) ,...),則可以使用這些成員的函數。

您需要查看png.h (或它的文檔),找出png_infop類型的指針,然后找出應該如何訪問其字段。 假設此指針確實是從中獲取數據的正確方法,那么您要么需要從其他標頭中包含該類型的定義(以便編譯器知道其數據成員的width等),要么有getter函數您應該調用帶有png_infop參數並返回所需信息。

[編輯:看起來您應該使用png_get_IHDRpng_get_image_width等。]

我在Mac OS X 10.6.8上成功編譯了該項目。

git clone https://github.com/Ramblurr/PietCreator.git   
cd PietCreator
mkdir build
cd build
cmake ../

-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Checking whether C compiler has -isysroot
-- Checking whether C compiler has -isysroot - yes
-- Checking whether C compiler supports OSX deployment target flag
-- Checking whether C compiler supports OSX deployment target flag - yes
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Checking whether CXX compiler has -isysroot
-- Checking whether CXX compiler has -isysroot - yes
-- Checking whether CXX compiler supports OSX deployment target flag
-- Checking whether CXX compiler supports OSX deployment target flag - yes
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Looking for Q_WS_X11
-- Looking for Q_WS_X11 - not found.
-- Looking for Q_WS_WIN
-- Looking for Q_WS_WIN - not found.
-- Looking for Q_WS_QWS
-- Looking for Q_WS_QWS - not found.
-- Looking for Q_WS_MAC
-- Looking for Q_WS_MAC - found
-- Looking for QT_MAC_USE_COCOA
-- Looking for QT_MAC_USE_COCOA - found
-- Found Qt-Version 4.7.4 (using /usr/local/bin/qmake)
-- Looking for gdImagePng in /usr/local/lib/libgd.dylib
-- Looking for gdImagePng in /usr/local/lib/libgd.dylib - found
-- Found ZLIB: /usr/include (found version "1.2.3")
-- Found PNG: /usr/X11R6/lib/libpng.dylib 
-- Looking for gdImageJpeg in /usr/local/lib/libgd.dylib
-- Looking for gdImageJpeg in /usr/local/lib/libgd.dylib - found
-- Found JPEG: /usr/local/lib/libjpeg.dylib 
-- Looking for gdImageGif in /usr/local/lib/libgd.dylib
-- Looking for gdImageGif in /usr/local/lib/libgd.dylib - found
-- Found GD: /usr/local/lib/libgd.dylib
-- Found GIF: /usr/local/lib/libgif.dylib 
-- Looking for include files HAVE_GD_H
-- Looking for include files HAVE_GD_H - found
-- Looking for include files HAVE_PNG_H
-- Looking for include files HAVE_PNG_H - not found.
-- Looking for include files HAVE_GIF_LIB_H
-- Looking for include files HAVE_GIF_LIB_H - found
-- Configuring done
-- Generating done
-- Build files have been written to: /Developer/workspace/png/PietCreator/build

運行后, make應用程序成功編譯:

Linking CXX executable pietcreator
[ 95%] Built target pietcreator
[ 97%] Generating NPietTest.moc
Scanning dependencies of target npiettest
[100%] Building CXX object npiet/CMakeFiles/npiettest.dir/test/NPietTest.cpp.o
Linking CXX executable npiettest
[100%] Built target npiettest

我遇到的唯一問題都與執行cmake ../時缺少依賴項有關。 我必須下載/編譯/安裝Qt 4.7.4Qt-mobility 1.2.0 在那之后,我還需要libgdgiflib,但是后來我使用brew來完成這項工作。

我建議您嘗試另一個git clone然后嘗試從頭開始再次編譯它。

如果您想知道, brew安裝了gd 2.0.36RC1giflib 4.1.6

當標題中包含前向聲明,並且源文件中沒有包含對應類的文件時,通常會出現此錯誤:

//header.h
class B;
class A{
A();
B* b;
}

//source.cpp
#include "header.h"
//include "B.h" //include header where B is defined to prevent error
A::A()
{
   b->foo(); //error, B is only a forward declaration
}

因此,您需要包括適當的標頭,向前聲明是不夠的。

當您具有以下結構時,通常會發生不完整的引用錯誤:

struct foo;

int bar(void) {
     struct foo *p;
     p->a = 0;
}

這里聲明了foo結構,但是其實際內容未知,並且將產生對不完整類型錯誤的引用。

其背后的原理是強制使用正式的API來操縱數據結構。 這樣可以確保將來的API可以更輕松地更改結構,而不會影響舊版程序。

因此,通常,API標頭將執行以下操作:

/*
 * foo.h part of foo API 
 */

struct foo;

extern void foo_set_a(struct foo *p, int value);
extern int foo_get_a(struct foo *p);

它將在內部實現foo API函數...例如:

/* 
 * foo.c ... implements foo API 
 */

struct foo {
   int a;
};

void foo_set_a(struct foo *p, int value) {
    p->a = value;
}

int foo_get_a(struct foo *p) {
    return p->a;
}

然后foo API的用戶可以:

use_foo() {
    struct foo *my_foo;
    foo_set_a(my_foo, 1);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM