1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
      go語言調(diào)用cdll go語言調(diào)用c的回調(diào)函數(shù)

      C# 調(diào)用 Golang DLL

      注意, import "C" 需要系統(tǒng)中安裝gcc,否則會(huì)報(bào)錯(cuò):

      創(chuàng)新互聯(lián)致力于互聯(lián)網(wǎng)網(wǎng)站建設(shè)與網(wǎng)站營(yíng)銷,提供成都做網(wǎng)站、網(wǎng)站制作、網(wǎng)站開發(fā)、seo優(yōu)化、網(wǎng)站排名、互聯(lián)網(wǎng)營(yíng)銷、成都微信小程序、公眾號(hào)商城、等建站開發(fā),創(chuàng)新互聯(lián)網(wǎng)站建設(shè)策劃專家,為不同類型的客戶提供良好的互聯(lián)網(wǎng)應(yīng)用定制解決方案,幫助客戶在新的全球化互聯(lián)網(wǎng)環(huán)境中保持優(yōu)勢(shì)。

      完成之后,使用go命令導(dǎo)出DLL文件

      執(zhí)行文件完成之后,會(huì)在目錄下生成main.dll 和 main.h 文件。

      輸出結(jié)果:

      需要注意:

      如何在golang 中調(diào)用c的靜態(tài)庫(kù)或者動(dòng)態(tài)庫(kù)

      Cgo 使得Go程序能夠調(diào)用C代碼. cgo讀入一個(gè)用特別的格式寫的Go語言源文件, 輸出Go和C程序, 使得C程序能打包到Go語言的程序包中.

      舉例說明一下. 下面是一個(gè)Go語言包, 包含了兩個(gè)函數(shù) -- Random 和 Seed -- 是C語言庫(kù)中random和srandom函數(shù)的馬甲.

      package rand

      /*

      #include stdlib.h

      */ import "C" func Random() int { return int(C.random()) } func Seed(i int) { C.srandom(C.uint(i)) }

      我們來看一下這里都有什么內(nèi)容. 開始是一個(gè)包的導(dǎo)入語句.

      rand包導(dǎo)入了"C"包, 但你會(huì)發(fā)現(xiàn)在Go的標(biāo)準(zhǔn)庫(kù)里沒有這個(gè)包. 那是因?yàn)镃是一個(gè)"偽包", 一個(gè)為cgo引入的特殊的包名, 它是C命名空間的一個(gè)引用.

      rand 包包含4個(gè)到C包的引用: 調(diào)用 C.random和C.srandom, 類型轉(zhuǎn)換 C.uint(i)還有引用語句.

      Random函數(shù)調(diào)用libc中的random函數(shù), 然后回返結(jié)果. 在C中, random返回一個(gè)C類型的長(zhǎng)整形值, cgo把它輪換為C.long. 這個(gè)值必需轉(zhuǎn)換成Go的類型, 才能在Go程序中使用. 使用一個(gè)常見的Go類型轉(zhuǎn)換:

      func Random() int { return int(C.random()) }

      這是一個(gè)等價(jià)的函數(shù), 使用了一個(gè)臨時(shí)變量來進(jìn)行類型轉(zhuǎn)換:

      func Random() int { var r C.long = C.random() return int(r) }

      Seed函數(shù)則相反. 它接受一個(gè)Go語言的int類型, 轉(zhuǎn)換成C語言的unsigned int類型, 然后傳遞給C的srandom函數(shù).

      func Seed(i int) { C.srandom(C.uint(i)) }

      需要注意的是, cgo中的unsigned int類型寫為C.uint; cgo的文檔中有完整的類型列表.

      這個(gè)例子中還有一個(gè)細(xì)節(jié)我們沒有說到, 那就是導(dǎo)入語句上面的注釋.

      /*

      #include stdlib.h

      */ import "C"

      Cgo可以識(shí)別這個(gè)注釋, 并在編譯C語言程序的時(shí)候?qū)⑺?dāng)作一個(gè)頭文件來處理. 在這個(gè)例子中, 它只是一個(gè)include語句, 然而其實(shí)它可以是使用有效的C語言代碼. 這個(gè)注釋必需緊靠在import "C"這個(gè)語句的上面, 不能有空行, 就像是文檔注釋一樣.

      Strings and things

      與Go語言不同, C語言中沒有顯式的字符串類型. 字符串在C語言中是一個(gè)以0結(jié)尾的字符數(shù)組.

      Go和C語言中的字符串轉(zhuǎn)換是通過C.CString, C.GoString,和C.GoStringN這些函數(shù)進(jìn)行的. 這些轉(zhuǎn)換將得到字符串類型的一個(gè)副本.

      下一個(gè)例子是實(shí)現(xiàn)一個(gè)Print函數(shù), 它使用C標(biāo)準(zhǔn)庫(kù)中的fputs函數(shù)把一個(gè)字符串寫到標(biāo)準(zhǔn)輸出上:

      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程序中進(jìn)行的內(nèi)存分配是不能被Go語言的內(nèi)存管理器感知的. 當(dāng)你使用C.CString創(chuàng)建一個(gè)C字符串時(shí)(或者其它類型的C語言內(nèi)存分配), 你必需記得在使用完后用C.free來釋放它.

      調(diào)用C.CString將返回一個(gè)指向字符數(shù)組開始處的指錯(cuò), 所以在函數(shù)退出前我們把它轉(zhuǎn)換成一個(gè)unsafe.Pointer(Go中與C的void 等價(jià)的東西), 使用C.free來釋放分配的內(nèi)存. 一個(gè)慣用法是在分配內(nèi)存后緊跟一個(gè)defer(特別是當(dāng)這段代碼比較復(fù)雜的時(shí)候), 這樣我們就有了下面這個(gè)Print函數(shù):

      func Print(s string) { cs := C.CString(s) defer C.free(unsafe.Pointer(cs)) C.fputs(cs, (*C.FILE)(C.stdout)) }

      構(gòu)建 cgo 包

      如果你使用goinstall, 構(gòu)建cgo包就比較容易了, 只要調(diào)用像平常一樣使用goinstall命令, 它就能自動(dòng)識(shí)別這個(gè)特殊的import "C", 然后自動(dòng)使用cgo來編譯這些文件.

      如果你想使用Go的Makefiles來構(gòu)建, 那在CGOFILES變量中列出那些要用cgo處理的文件, 就像GOFILES變量包含一般的Go源文件一樣.

      rand包的Makefile可以寫成下面這樣:

      include $(GOROOT)/src/Make.inc

      TARG=goblog/rand

      CGOFILES=\ rand.go\ include $(GOROOT)/src/Make.pkg

      然后輸入gomake開始構(gòu)建.

      更多 cgo 的資源

      cgo的文檔中包含了關(guān)于C偽包的更多詳細(xì)的說明, 以及構(gòu)建過程. Go代碼樹中的cgo的例子給出了更多更高級(jí)的用法.

      一個(gè)簡(jiǎn)單而又符合Go慣用法的基于cgo的包是Russ Cox寫的gosqlite. 而Go語言的網(wǎng)站上也列出了更多的的cgo包.

      最后, 如果你對(duì)于cgo的內(nèi)部是怎么運(yùn)作這個(gè)事情感到好奇的話, 去看看運(yùn)行時(shí)包的cgocall.c文件的注釋吧.

      go語言如何調(diào)用c函數(shù)

      直接嵌入c源代碼到go代碼里面

      package main

      /*

      #include stdio.h

      void myhello(int i) {

      printf("Hello C: %d\n", i);

      }

      */

      import "C"

      import "fmt"

      func main() {

      C.myhello(C.int(12))

      fmt.Println("Hello Go");

      }

      需要注意的是C代碼必須放在注釋里面

      import "C"語句和前面的C代碼之間不能有空行

      運(yùn)行結(jié)果

      $ go build main.go ./main

      Hello C: 12

      Hello Go

      分開c代碼到單獨(dú)文件

      嵌在一起代碼結(jié)構(gòu)不是很好看,很多人包括我,還是喜歡把兩個(gè)分開,放在不同的文件里面,顯得干凈,go源文件里面是go的源代碼,c源文件里面是c的源代碼。

      $ ls

      hello.c hello.h main.go

      $ cat hello.h

      void hello(int);

      $ cat hello.c

      #include stdio.h

      void hello(int i) {

      printf("Hello C: %d\n", i);

      }

      $ cat main.go

      package main

      // #include "hello.h"

      import "C"

      import "fmt"

      func main() {

      C.hello(C.int(12))

      fmt.Println("Hello Go");

      }

      編譯運(yùn)行

      $ go build ./main

      Hello C: 12

      Hello Go

      編譯成庫(kù)文件

      如果c文件比較多,最好還是能夠編譯成一個(gè)獨(dú)立的庫(kù)文件,然后go來調(diào)用庫(kù)。

      $ find mylib main

      mylib

      mylib/hello.h

      mylib/hello.c

      main

      main/main.go

      編譯庫(kù)文件

      $ cd mylib

      # gcc -fPIC -shared -o libhello.so hello.c

      編譯go程序

      $ cd main

      $ cat main.go

      package main

      // #cgo CFLAGS: -I../mylib

      // #cgo LDFLAGS: -L../mylib -lhello

      // #include "hello.h"

      import "C"

      import "fmt"

      func main() {

      C.hello(C.int(12))

      fmt.Println("Hello Go");

      }

      $ go build main.go

      運(yùn)行

      $ export LD_LIBRARY_PATH=../mylib

      $ ./main

      Hello C: 12

      Hello Go

      在我們的例子中,庫(kù)文件是編譯成動(dòng)態(tài)庫(kù)的,main程序鏈接的時(shí)候也是采用的動(dòng)態(tài)庫(kù)

      $ ldd main

      linux-vdso.so.1 = (0x00007fffc7968000)

      libhello.so = ../mylib/libhello.so (0x00007f513684c000)

      libpthread.so.0 = /lib64/libpthread.so.0 (0x00007f5136614000)

      libc.so.6 = /lib64/libc.so.6 (0x00007f5136253000)

      /lib64/ld-linux-x86-64.so.2 (0x000055d819227000)

      理論上講也是可以編譯成整個(gè)一靜態(tài)鏈接的可執(zhí)行程序,由于我的機(jī)器上缺少靜態(tài)鏈接的系統(tǒng)庫(kù),比如libc.a,所以只能編譯成動(dòng)態(tài)鏈接。

      golang可以調(diào)用C++的動(dòng)態(tài)鏈接庫(kù)么

      可以,dll .so .a均可以調(diào)用,實(shí)測(cè)過。用CGO就行

      需要注意:庫(kù)導(dǎo)出接口時(shí),以C風(fēng)格導(dǎo)出,否則c++里對(duì)函數(shù)命名可能導(dǎo)致調(diào)用不到。

      golang中調(diào)用c的正確姿勢(shì)

      工程結(jié)構(gòu)如上圖所示,我們需要實(shí)現(xiàn)的目標(biāo)是在go文件中調(diào)用c文件

      foo.c如下:

      foo.go如下

      foo.h如下:

      編譯過程如下:

      1、先將c文件編譯為.o文件,然后生成動(dòng)態(tài)鏈接庫(kù).dylib文件

      (1) clang -c foo.c

      (2 clang -shared foo.o -o libfoo.dylib

      2、在上述的動(dòng)態(tài)鏈接庫(kù)生成之后,在foo.go中添加動(dòng)態(tài)鏈接命令:#cgo LDFLAGS: -L./ -lfoo

      需要注意的是

      中間不能有空格


      網(wǎng)站名稱:go語言調(diào)用cdll go語言調(diào)用c的回調(diào)函數(shù)
      本文URL:http://www.ef60e0e.cn/article/hhccic.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        车致| 盈江县| 东台市| 西盟| 大洼县| 基隆市| 玉龙| 化隆| 贺兰县| 闻喜县| 伊宁市| 山东省| 栖霞市| 许昌县| 蓬莱市| 咸阳市| 克什克腾旗| 福安市| 双牌县| 开阳县| 共和县| 余庆县| 中西区| 华安县| 津南区| 琼结县| 梁平县| 威海市| 南部县| 温州市| 天水市| 东明县| 南汇区| 石林| 开阳县| 肇东市| 金乡县| 灌南县| 定安县| 黄大仙区| 章丘市|