日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC++编译libpng

發布時間:2025/3/21 c/c++ 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC++编译libpng 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

1簡介????1

2 Visual C++6.0????2

2.1 打開項目????2

2.2 編譯宏????3

2.2.1 小結????5

3 Visual C++2010????6

3.1 打開項目????6

3.2 編譯宏????6

3.2.1 PNG_USE_DLL????6

3.2.2 Z_SOLO????7

3.3 自定義編譯????8

3.4 自定義環境變量????8

3.4.1 定義????9

3.4.2 使用????9

?

?

1簡介

libpng是一個讀寫 .png 文件的 C 函數庫,其下載網址如下:

http://sourceforge.net/projects/libpng/files

本文對libpng自帶的Visual C++項目進行剖析。

?

?

2 Visual C++6.0

2.1 打開項目

版本1.0.63至版本1.4.16libpng帶有Visual C++6.0的項目。本章以版本1.4.12進行說明。假定其存放目錄為V:\libpng\v1.4.12,如下圖所示:

VC++6.0的工作區文件位于V:\libpng\v1.4.12\projects\visualc6\libpng.dsw。首先使用記事本打開這個文件,其內容節選如下:

也就是說libpng.dsw包含了項目zlib.dsp,后者的存放路徑為V:\libpng\v1.4.12\projects\visualc6\..\..\..\zlib\projects\visualc6\zlib.dsp,即V:\libpng\zlib\projects\visualc6\zlib.dsp

zlib也是一個開源的C函數庫,其版本1.2.21.2.31.2.4帶有Visual C++6.0的項目。這里,把版本1.2.3zlib復制到V:\libpng\zlib,其目錄結構如下圖所示:

現在,可以使用VC++6.0打開V:\libpng\v1.4.12\projects\visualc6\libpng.dsw了。

2.2 編譯宏

項目libpng5個配置項,如下圖所示:

"Win32 DLL Release"生成Release版的動態庫;

"Win32 DLL Debug"生成Debug版的動態庫,用于調試程序;

"Win32 DLL VB"生成供非C語言(如:VB6.0)調用的動態庫;

"Win32 LIB Release"生成Release版的靜態庫;

"Win32 LIB Debug"生成Debug版的靜態庫,用于調試程序。

"Win32 DLL Release"和"Win32 DLL Debug"定義了宏PNG_BUILD_DLL

"Win32 DLL VB"定義了宏PNG_BUILD_DLL,PNGAPI=__stdcall,PNG_NO_MODULEDEF

"Win32 LIB Release"和"Win32 LIB Debug"沒有定義特殊的宏。

這些宏都有什么含義呢?

先看看libpng的一個接口函數定義:

PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));

PNG_EXPORT有兩份定義,最終形式是一致的即:

#define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol

展開宏PNG_EXPORTPNGARG,函數png_set_expand的聲明如下:

PNG_IMPEXP void PNGAPI png_set_expand(png_structp png_ptr);

PNGAPI默認為 __cdecl,"Win32 DLL VB"配置項里強制規定它為__stdcall。因為VB6.0只能調用__stdcall的函數。

接下來的關鍵是PNG_IMPEXP,它有三份定義:

//1份定義("Win32 DLL Release"和"Win32 DLL Debug")

#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)

# define PNG_IMPEXP

#endif

?

//2份定義("Win32 LIB Release"和"Win32 LIB Debug")

# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \

0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)

# define PNG_IMPEXP

# endif

?

//3份定義"Win32 DLL VB"

# ifndef PNG_IMPEXP

# ifdef PNG_BUILD_DLL

# define PNG_IMPEXP __declspec(dllexport)

# else

# define PNG_IMPEXP __declspec(dllimport)

# endif

# endif

也就是說:選中配置"Win32 DLL VB"函數png_set_expand的聲明如下:

__declspec(dllexport) void __stdcall png_set_expand(png_structp png_ptr);

否則函數png_set_expand的聲明如下:

void __cdecl png_set_expand(png_structp png_ptr);

項目pngtest的"Win32 DLL Release"和"Win32 DLL Debug"用到了libpng的動態庫,它們都定義了宏PNG_DLL。此時函數png_set_expand的聲明如下:

__declspec(dllimport) void __cdecl png_set_expand(png_structp png_ptr);

2.2.1 小結

1PNGAPI規定了導出函數的調用約定,默認為__cdecl,可強制改為__stdcall

2、編譯生成libpng動態庫時,請定義宏PNG_BUILD_DLL

3、如果使用.def文件,請不要定義宏PNG_NO_MODULEDEF,導出函數前沒有__declspec(dllexport),編譯器通過.def文件自動導出函數;pngwin.def文件在"Win32 DLL VB"下是被排除編譯的,如下圖所示。因為沒有使用.def文件,因此需要定義宏PNG_NO_MODULEDEF,給導出函數增加__declspec(dllexport)修飾符;

4、客戶端程序要使用libpng動態庫,請定義宏PNG_DLL,它會給導出函數前增加__declspec(dllimport)修飾符。

?

3 Visual C++2010

3.1 打開項目

版本1.4.12至版本1.6.18libpng帶有Visual C++2010的項目。本章以版本1.6.18進行說明。假定其存放目錄為V:\libpng\v1.6.18,如下圖所示:

使用vc2010打開V:\libpng\v1.6.18\projects\vstudio\vstudio.sln

3.2 編譯宏

3.2.1 PNG_USE_DLL

libpng沒有定義什么特殊的宏。客戶端程序pngstestpngunknownpngvalid在使用libpng動態庫時,定義了宏PNG_USE_DLL

現在簡單了,只要記住宏PNG_USE_DLL即可。問題是:libpng是如何簡化這個問題的?

首先看pngpriv.h,這是libpng內部使用的頭文件。

#ifndef PNG_BUILD_DLL

#ifdef DLL_EXPORT

#else

#ifdef _WINDLL

#define PNG_BUILD_DLL

#else

#endif

#endif

#endif

?

#ifndef PNG_IMPEXP

#ifdef PNG_BUILD_DLL

#define PNG_IMPEXP PNG_DLL_EXPORT

#else

#define PNG_IMPEXP

#endif

#endif

當編譯生成libpng動態庫時,宏_WINDLL被定義。上面的代碼將定義PNG_BUILD_DLL,并定義PNG_IMPEXPPNG_DLL_EXPORT,即__declspec(dllexport)

當編譯生成libpng靜態庫時,宏PNG_BUILD_DLL不會被定義,因此PNG_IMPEXP會被定義為空。

這里有必要說明一下宏_WINDLL,在VC++6.0里它的含義是:是否使用MFC共享庫,使用了就會定義它,未使用就不會定義它。所以,這里用_WINDLL是不兼容VC++6.0的,為了兼容VC++6.0應該把_WINDLL更改為_USERDLL

再來看看客戶端程序,它會包含png.h,后者會包含pngconf.h。下面的代碼節選自pngconf.h

#ifndef PNG_IMPEXP

# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)

/* This forces use of a DLL, disallowing static linking */

# define PNG_IMPEXP PNG_DLL_IMPORT

# endif

?

# ifndef PNG_IMPEXP

# define PNG_IMPEXP

# endif

#endif

很簡單:定義PNG_USE_DLL時,PNG_IMPEXPPNG_DLL_IMPORT__declspec(dllimport);未定義PNG_USE_DLL時,PNG_IMPEXP為空。

3.2.2 Z_SOLO

編譯zlib時用到了宏Z_SOLO。它的含義是對zlib進行裁剪。zlib被裁剪后,以下函數不會被實現:

compress,compress2,compressBound,gzFile,gz_error,gz_intmax,gz_strwinerror,gzbuffer,gzclearerr,gzclose,gzclose_r,gzclose_w,gzdirect,gzdopen,gzeof,gzerror,gzflush,gzgetc,gzgetc_,gzgets,gzoffset,gzoffset64,gzopen,gzopen64,gzopen_w,gzprintf,gzputc,gzputs,gzread,gzrewind,gzseek,gzseek64,gzsetparams,gztell,gztell64,gzungetc,gzvprintf,gzwrite,uncompress,zcalloc,zcfree

簡而言之就是libpng用不了那么多的zlib函數,編譯時對zlib進行了裁剪。

3.3 自定義編譯

libpng依賴于pnglibconfpnglibconf沒有任何文件,編譯時它做了什么?

它其實就做了一件事兒——復制文件。如下圖所示:

編譯pnglibconf時將執行自定義編譯。上圖里就是執行如下命令

copy ..\..\..\scripts\pnglibconf.h.prebuilt ..\..\..\pnglibconf.h

上面的相對路徑是相對于項目文件V:\libpng\v1.6.18\projects\vstudio\pnglibconf\pnglibconf.vcxproj的,所以其實就是把V:\libpng\v1.6.18\scripts\pnglibconf.h.prebuilt復制到V:\libpng\v1.6.18\pnglibconf.h

3.4 自定義環境變量

選中zlib項目的任一文件,可以查看它的屬性。如下圖所示:

上圖的ZLibSrcDir就是一個環境變量,它指明了zlib源代碼所在的目錄。

3.4.1 定義

ZLibSrcDir的定義在文件V:\libpng\v1.6.18\projects\vstudio\zlib.props里,如下圖所示:

上圖將設置環境變量ZLibSrcDir..\..\..\..\zlib-1.2.8

3.4.2 使用

需要使用環境變量ZLibSrcDir的項目,請在相應的.vcxproj文件里插入一行語句,如下圖所示:

ZLibSrcDir是一個相對路徑,它是相對于各個vc項目文件的(*.vcxproj)。以libpng.vcxproj為例,該文件位于V:\libpng\v1.6.18\projects\vstudio\libpng,因此ZLibSrcDir指向的絕對路徑就是V:\libpng\v1.6.18\projects\vstudio\libpng\..\..\..\..\zlib-1.2.8,即V:\libpng\zlib-1.2.8。也就是說需要把zlib-1.2.8的文件都復制到V:\libpng\zlib-1.2.8目錄,或者修改環境變量ZLibSrcDir

使用環境變量ZLibSrcDir指向zlib源代碼的位置,這是個非常好的功能。

轉載于:https://www.cnblogs.com/hanford/p/6168813.html

總結

以上是生活随笔為你收集整理的VC++编译libpng的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。