2017-06-01 139 views
1

我在庫初學者鏈接,並花了兩天時間試圖將libcrypto庫上的Visual Studio 2017年鏈接到我的C程序。
我不得不包括applink.c來解決我的問題。但我認爲這是非常奇怪的包括東西這不是一個頭。在網上搜索了一下之後,我瞭解到包括一個源文件是存在的,但應該避免這樣做。爲什麼然後openssl library不?C:包括源文件,而不是頭

我不認爲它是特別相關的,但這裏是這個源文件的小概述,你可以找到整個源文件here

#define APPLINK_OPEN 18  /* formally can't be used, as flags can vary */ 
#define APPLINK_READ 19 
#define APPLINK_WRITE 20 
#define APPLINK_LSEEK 21 
#define APPLINK_CLOSE 22 
#define APPLINK_MAX  22  /* always same as last macro */ 

#ifndef APPMACROS_ONLY 
# include <stdio.h> 
# include <io.h> 
# include <fcntl.h> 

static void *app_stdin(void) 
{ 
    return stdin; 
} 

static void *app_stdout(void) 
{ 
    return stdout; 
} 

if (once) { 
     OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin; 
     OPENSSL_ApplinkTable[APPLINK_STDOUT] = app_stdout; 
     OPENSSL_ApplinkTable[APPLINK_STDERR] = app_stderr; 
     OPENSSL_ApplinkTable[APPLINK_FPRINTF] = fprintf; 
     OPENSSL_ApplinkTable[APPLINK_FGETS] = fgets; 
     OPENSSL_ApplinkTable[APPLINK_FREAD] = fread; 
     OPENSSL_ApplinkTable[APPLINK_FWRITE] = fwrite; 
     OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod; 
     OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof; 
     OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose; 

     OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen; 
     OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek; 
     OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell; 
     OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush; 
     OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror; 
     OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr; 
     OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno; 

     OPENSSL_ApplinkTable[APPLINK_OPEN] = _open; 
     OPENSSL_ApplinkTable[APPLINK_READ] = _read; 
     OPENSSL_ApplinkTable[APPLINK_WRITE] = _write; 
     OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek; 
     OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close; 

     once = 0; 
} 

包含頭文件和源文件有什麼區別?有什麼缺點和優點呢?

這個職位不是要求的方式來解決鏈路問題

+1

那麼,openssl不是我們所說的「編程良好的庫」...... – Stargateur

+1

[您只能定義一個函數](http://en.cppreference.com/w/cpp/language/definition) (除少數例外)。如果你要包含一個源文件,你可以在每個包含它的文件中定義每個函數*。如果您只包含一次文件(如果只將其包含在另一個源文件中),則可以避開它。您的問題很可能是您沒有編譯該指定的源文件,或者沒有與其鏈接。由於您使用的是Visual Studio,因此您應該將其作爲源文件簡單地添加到項目中。 –

+0

@FrançoisAndrieux這是錯誤的,除非他從頭文件中包含applink.c文件。請注意這裏的'static'關鍵字。 –

回答

-1

包括文件就像將文件複製到你的C文件。

這意味着任何包含C文件的東西都會在applink.c中擁有自己的函數副本。 您還會注意到它們被聲明爲「靜態」,這意味着這些副本對其各自的文件是本地的,並且不會產生衝突。他們甚至可能會被內聯。

一般來說,這是一方面二進制大小和編譯時間之間的折衷,另一方面是運行速度和代碼簡單性。

這不是一件罕見的事情要看,更令我驚訝的是它是.c而不是.h。

+0

通過擁有多個函數的靜態副本,沒有運行時速度的提高。代碼簡化優勢也沒有。 (只有'inline'有優勢。) –

+0

少文件=簡單,不是嗎?至於速度,我認爲基準是有序的。我的印象是速度更快,因爲標題功能很可能被內聯。 –

+0

山姆,我認爲包括一個.c文件是不好的做法。包括定義'inline'函數的.h文件是可以的;這些不會導致通話開銷。 –