首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Go 與 C 互調實戰:cgo 導出/調用函數完整範例

     編輯:關於C語言

項目結構

src/
  testcgowin/
    cthread.go        // Go 代碼
    cthread_windows.c // C 代碼
    testcgowin.go     // 主程序

關鍵機制:cgo 指令註釋

Go 文件頂部緊跟package聲明:


// extern void doAdd(int, int);
import "C"
  • // extern ...:聲明 C 函數供 Go 調用,等同#include頭文件。
  • import "C":觸發 cgo 處理,**必須緊跟上一行,中間無空行**。

Go 導出函數給 C 調用


//export Add
func Add(x int) {
    sum.Lock()
    sum.i += x
    sum.Unlock()
    var p *int
    *p = 2 // 故意 panic 測試 recover
}
  • //export Add:標記導出,C 端可直接調用Add。
  • 無此註釋鏈接報錯undefined reference to 'Add'。

C 代碼調用 Go 函數


// cthread_windows.c
#define WIN32_LEAN_AND_MEAN
#include 
#include 
#include "_cgo_export.h" // cgo 生成的頭文件,含 Go 導出函數聲明

static unsigned int __stdcall addThread(void *arg) {
    int max = *(int*)arg;
    for (int i = 0; i < max; i++) Add(i);
    return 0;
}

void doAdd(int max, int nthread) {
    HANDLE threads[20];
    for (int i = 0; i < nthread; i++)
        threads[i] = (HANDLE)_beginthreadex(NULL, 0, addThread, &max, 0, NULL);
    for (int i = 0; i < nthread; i++) {
        WaitForSingleObject(threads[i], INFINITE);
        CloseHandle(threads[i]);
    }
}
  • #include "_cgo_export.h":獲取 Go 導出函數聲明。
  • static修飾內部線程函數,避免符號污染。
  • Windows 線程用_beginthreadex/WaitForSingleObject。

構建與使用

  1. 運行go generate或go build觸發 cgo,生成_obj/、_cgo_export.h。
  2. go install產出testcgowin.a靜態庫。
  3. 主程序直接import "testcgowin"調用TestCthread()。

核心要點總結

  • 雙向調用全靠//extern和//export註釋驅動 cgo 代碼生成。
  • C 文件放同目錄自動編譯鏈接,無需手動指定。
  • 類型轉換:Goint↔Cint,指針傳遞需unsafe.Pointer。
  • Go 運行時管理內存,C 端不得持有 Go 指針跨越調用邊界。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved