c語言調用靜態庫
庫函數的源碼你是看不到的。要找實現的話得去網路。自帶的都是編譯好的東西(用到時直接調用)不是原C程序。
至於sin()的實現。如果你學過高數應該知道泰勒展開。
不知道的話直接給你公式:sin(x)=x-(x^3)/3!+(x^5)/5!+...(按這規律求和下去,x是弧度)
用一個for循環。要精確的話循環的次數多些就行
B. C語言 靜態庫之間可以相互調用么
可以的,天津lib和.h文件到項目,然後就可以調用。
但是必須有一個被動,一個主動,你不要搞成間接遞歸。
C. C語言,用一個庫,比如OpenSSL的時候,為什麼要分靜態庫和頭文件呢。有
首先你要知道什麼是介面,什麼是實現, 一個函數的聲明稱為介面,一個函數的定義叫實現,我們用一個庫時,首先要包含庫的頭文件,即導入庫的介面,目的是為了在編譯階段檢查有關調用庫函數的代碼時是否是正確的函數原型或數據結構類型等,注意,只是為了編譯時檢查。庫是將所有的函數實現並編譯成二進制文件,最終只有你的程序編譯之後再和庫的二進制文件做一個鏈接,才能形成一個包含庫代碼的可執行文件,這種庫稱為靜態庫,還有一種庫叫動態庫,有一些庫的代碼會被多個應用程序鏈接使用,這時如果還採用靜態庫的話,那麼每個應用程序都會擁有一份這個庫的二進制代碼,這樣造成內存資源浪費,所以操作系統為了避免浪費,先將一些通用的庫代碼運行起來,一旦運行起來,那麼這個庫中的函數就有了地址,那麼我們的應用程序為了使用這個庫的代碼,只需要在載入前知道這些函數的地址即可完成對庫的代碼的調用。
D. 如何在golang 中調用c的靜態庫或者動態庫
Cgo 使得Go程序能夠調用C代碼. cgo讀入一個用特別的格式寫的Go語言源文件, 輸出Go和C程序, 使得C程序能打包到Go語言的程序包中.
舉例說明一下. 下面是一個Go語言包, 包含了兩個函數 -- Random 和 Seed -- 是C語言庫中random和srandom函數的馬甲.
package rand
/*
#include <stdlib.h>
*/ import "C" func Random() int { return int(C.random()) } func Seed(i int) { C.srandom(C.uint(i)) }
我們來看一下這里都有什麼內容. 開始是一個包的導入語句.
rand包導入了"C"包, 但你會發現在Go的標准庫里沒有這個包. 那是因為C是一個"偽包", 一個為cgo引入的特殊的包名, 它是C命名空間的一個引用.
rand 包包含4個到C包的引用: 調用 C.random和C.srandom, 類型轉換 C.uint(i)還有引用語句.
Random函數調用libc中的random函數, 然後回返結果. 在C中, random返回一個C類型的長整形值, cgo把它輪換為C.long. 這個值必需轉換成Go的類型, 才能在Go程序中使用. 使用一個常見的Go類型轉換:
func Random() int { return int(C.random()) }
這是一個等價的函數, 使用了一個臨時變數來進行類型轉換:
func Random() int { var r C.long = C.random() return int(r) }
Seed函數則相反. 它接受一個Go語言的int類型, 轉換成C語言的unsigned int類型, 然後傳遞給C的srandom函數.
func Seed(i int) { C.srandom(C.uint(i)) }
需要注意的是, cgo中的unsigned int類型寫為C.uint; cgo的文檔中有完整的類型列表.
這個例子中還有一個細節我們沒有說到, 那就是導入語句上面的注釋.
/*
#include <stdlib.h>
*/ import "C"
Cgo可以識別這個注釋, 並在編譯C語言程序的時候將它當作一個頭文件來處理. 在這個例子中, 它只是一個include語句, 然而其實它可以是使用有效的C語言代碼. 這個注釋必需緊靠在import "C"這個語句的上面, 不能有空行, 就像是文檔注釋一樣.
Strings and things
與Go語言不同, C語言中沒有顯式的字元串類型. 字元串在C語言中是一個以0結尾的字元數組.
Go和C語言中的字元串轉換是通過C.CString, C.GoString,和C.GoStringN這些函數進行的. 這些轉換將得到字元串類型的一個副本.
下一個例子是實現一個Print函數, 它使用C標准庫中的fputs函數把一個字元串寫到標准輸出上:
package print // #include <stdio.h> // #include <stdlib.h> import "C" import "unsafe" func Print(s string) { cs := C.CString(s) C.fputs(cs, (*C.FILE)(C.stdout)) C.free(unsafe.Pointer(cs)) }
在C程序中進行的內存分配是不能被Go語言的內存管理器感知的. 當你使用C.CString創建一個C字元串時(或者其它類型的C語言內存分配), 你必需記得在使用完後用C.free來釋放它.
調用C.CString將返回一個指向字元數組開始處的指錯, 所以在函數退出前我們把它轉換成一個unsafe.Pointer(Go中與C的void 等價的東西), 使用C.free來釋放分配的內存. 一個慣用法是在分配內存後緊跟一個defer(特別是當這段代碼比較復雜的時候), 這樣我們就有了下面這個Print函數:
func Print(s string) { cs := C.CString(s) defer C.free(unsafe.Pointer(cs)) C.fputs(cs, (*C.FILE)(C.stdout)) }
構建 cgo 包
如果你使用goinstall, 構建cgo包就比較容易了, 只要調用像平常一樣使用goinstall命令, 它就能自動識別這個特殊的import "C", 然後自動使用cgo來編譯這些文件.
如果你想使用Go的Makefiles來構建, 那在CGOFILES變數中列出那些要用cgo處理的文件, 就像GOFILES變數包含一般的Go源文件一樣.
rand包的Makefile可以寫成下面這樣:
include $(GOROOT)/src/Make.inc
TARG=goblog/rand
CGOFILES=\ rand.go\ include $(GOROOT)/src/Make.pkg
然後輸入gomake開始構建.
更多 cgo 的資源
cgo的文檔中包含了關於C偽包的更多詳細的說明, 以及構建過程. Go代碼樹中的cgo的例子給出了更多更高級的用法.
一個簡單而又符合Go慣用法的基於cgo的包是Russ Cox寫的gosqlite. 而Go語言的網站上也列出了更多的的cgo包.
最後, 如果你對於cgo的內部是怎麼運作這個事情感到好奇的話, 去看看運行時包的cgocall.c文件的注釋吧.
E. C語言調用靜態庫顯示"不是內部或外部命令,也不是可運行的程序或批處理文件"
你通過VS調試運行程序的時候默認會去查找程序目錄下面的Debug中的和項目同名的exe文件(你的情況是TEST.exe)。因為你編譯失敗了,exe文件沒有生成所以找不到這個文件去執行。你目前的情況看來是你嘗試用C的編譯器去編譯C++代碼(因為你創建的是.c文件)所以失敗。把文件名改成cpp重新編譯再試
F. c語言靜態庫能看到代碼嗎
可以。靜態庫:本質就是由若干個共享庫文件打包生成的靜態庫文件,鏈接靜態庫的本質就是將被調用的代碼指令復制到調用模塊中,體現在最終生成的可執行文件中。
G. 請教高手教一下用gcc編譯c語言函數,再合並為靜態庫,最後調用的過程。
應該編譯成.a文件
ar rc c:\libab.a c:\a.o c:\b.o
然後,再編譯執行文件
gcc -o c:\m.exe c:\m.c -LC:\ -lab
你這樣試試
H. C語言,用一個庫,比如OpenSSL的時候,為什麼要分靜態庫和頭文件呢。有
就像開車,沒方向盤,沒油門,不管怎樣的司機都沒法把車開起來。但是只有方向盤和油門,沒有輪子和發動機,車也不可能開起來。
庫文件就像輪子和發動機,沒有它,庫就是空殼而已,動不起來。但是只有輪子和發動機,也是不能用的,要讓它在合適的地方動起來,按自己的想法行動,到達自己想要的目的,就要包含頭文件,然後用頭文件提供的功能控制它的行動
I. linux怎樣實現c語言動態庫與靜態庫的鏈接
Linux系統中靜態庫是.a文件,編譯鏈接.a文件只需要加上.a文件的完整的文件路徑就可以了,比如:
gcc -o hello hello.c /usr/lib/libm.a
Linux系統的動態庫是系統中的.so文件,編譯鏈接動態庫需要用-L參數指定動態庫的搜索路徑,還要用-l(這個是小寫的L)指定動態庫的名字,比如:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
J. 用C語言寫的程序能調用C++寫的靜態庫嗎
能。只要協議匹配的靜態庫不管什麼語言寫的都能用。