第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何使用 CGo 為標(biāo)準(zhǔn)庫(kù)調(diào)用 C++ 變量

如何使用 CGo 為標(biāo)準(zhǔn)庫(kù)調(diào)用 C++ 變量

Go
慕斯王 2023-01-03 10:13:55
我正在嘗試使用 cgo 從 C++ 代碼中獲取變量值。對(duì)于以.hall 結(jié)尾的庫(kù)工作正常,但對(duì)于,等庫(kù)<iostream>,我收到以下錯(cuò)誤:<map><string>fatal error: iostream: No such file or directory    4 | #include <iostream>      |          ^~~~~~~~~~在我的代碼下面:package main/*#cgo LDFLAGS: -lc++#include <iostream>std::string plus() {    return "Hello World!\n";}*/import "C"import "fmt"func main() {    a := Plus_go()    fmt.Println(a)}func Plus_go() string {    return C.plus()}我添加了這個(gè)標(biāo)志,因?yàn)槲以趆ttps://stackoverflow.com/a/41615301/15024997#cgo LDFLAGS: -lc++的 stackoverflow 上的一個(gè)答案中看到了這個(gè)建議。我正在使用 VS Code(不是 VS Studio)、Windows 10、Go 1.18(最新版本)。我運(yùn)行了以下命令go tool cgo -debug-gcc mycode.go來跟蹤編譯器的執(zhí)行和輸出:$ gcc -E -dM -xc -m64 - <<EOF#line 1 "cgo-builtin-prolog"#include <stddef.h> /* for ptrdiff_t and size_t below *//* Define intgo when compiling with GCC.  */typedef ptrdiff_t intgo;#define GO_CGO_GOSTRING_TYPEDEFtypedef struct { const char *p; intgo n; } _GoString_;typedef struct { char *p; intgo n; intgo c; } _GoBytes_;_GoString_ GoString(char *p);_GoString_ GoStringN(char *p, int l);_GoBytes_ GoBytes(void *p, int n);char *CString(_GoString_);void *CBytes(_GoBytes_);void *_CMalloc(size_t);__attribute__ ((unused))static size_t _GoStringLen(_GoString_ s) { return (size_t)s.n; }__attribute__ ((unused))static const char *_GoStringPtr(_GoString_ s) { return s.p; }#line 3 "C:\\Users\\Home\\OneDrive\\Desktop\\DevicesC++\\devices.go"#include <iostream>std::string plus() {    return "Hello World!\n";}#line 1 "cgo-generated-wrapper"EOFC:\Users\Home\OneDrive\Desktop\DevicesC++\devices.go:5:10: fatal error: iostream: No such file or directory    5 | #include <iostream>      |          ^~~~~~~~~~compilation terminated.C:\Users\Home\OneDrive\Desktop\DevicesC++\devices.go:5:10: fatal error: iostream: No such file or directory    5 | #include <iostream>      |          ^~~~~~~~~~compilation terminated.
查看完整描述

1 回答

?
侃侃無極

TA貢獻(xiàn)2051條經(jīng)驗(yàn) 獲得超10個(gè)贊

CGo 允許您將 Go 代碼鏈接到實(shí)現(xiàn) C 風(fēng)格外部函數(shù)接口的代碼。這并不意味著您可以將任意語言代碼固定到位。


讓我們從第一個(gè)問題開始,即import "C"您的一個(gè) Go 文件中的行必須僅包含其上方的 C 代碼。那是:


/*

#include <stdlib.h>

extern char *cstyle_plus();

*/

可以,但是:


/*

#include <stdlib.h>

extern std::string *plus();

*/

不是,您也不能#include在這里使用任何 C++ 標(biāo)頭。為了稍微簡(jiǎn)化事情,這里的注釋實(shí)際上被剪掉并提供給C 編譯器。如果它不是有效的 C,它就不會(huì)編譯。


如果你想包含 C++ 代碼,你可以,但你必須將它放在一個(gè)或多個(gè)單獨(dú)的文件中(從技術(shù)上講,C 或 C++ 術(shù)語中的“翻譯單元”)。然后 CGo 將該文件編譯為目標(biāo)代碼。


然而,下一個(gè)問題是目標(biāo)代碼必須符合CGo 實(shí)現(xiàn)的 C外部函數(shù)接口。這意味著您的 C++ 代碼必須返回 C 類型(和/或接收此類類型作為參數(shù))。由于std::string不是 C 字符串,您實(shí)際上不能直接返回它。


它不是很有效(并且存在一些解決此問題的嘗試),但處理此問題的常用方法是讓 C 函數(shù)返回 C 風(fēng)格的“char *”或“const char *”字符串。如果字符串本身具有非靜態(tài)持續(xù)時(shí)間——就像你的那樣——你必須malloc在這里使用,特別是C malloc(std::malloc可能是不可互操作的)。


函數(shù)本身也必須可以從C 代碼調(diào)用。這意味著我們需要使用extern "C"它。


因此,我們的plus.cpp文件(或任何你想稱呼它的東西)可能會(huì)這樣讀:


#include <stdlib.h>

#include <iostream>


std::string plus() {

        return "Hello World!\n";

}


extern "C" {

char *cstyle_plus() {

        // Ideally we'd use strdup here, but Windows calls it _strdup

        char *ret = static_cast<char *>(malloc(plus().length() + 1));

        if (ret != NULL) {

                strcpy(ret, plus().c_str());

        }

        return static_cast<char *>(ret);

}

}

然后我們可以使用這個(gè)從 Go 中調(diào)用它main.go:


package main


/*

#include <stdlib.h>

extern char *cstyle_plus();

*/

import "C"

import (

        "fmt"

        "unsafe"

)


func Plus_go() string {

        s := C.cstyle_plus()

        defer C.free(unsafe.Pointer(s))

        return C.GoString(s)

}


func main() {

        a := Plus_go()

        fmt.Println(a)

}

添加一個(gè) trivialgo.mod和 building,生成的代碼運(yùn)行;雙換行是因?yàn)镃字符串里面有一個(gè)換行符,加fmt.Println了一個(gè)換行符:


$ go build

$ ./cgo_cpp

Hello World!


這段代碼有點(diǎn)草率:應(yīng)該malloc失敗,它返回 NULL,并將C.GoString其變成一個(gè)空字符串。然而,真正的代碼應(yīng)該盡量避免這種愚蠢的分配和釋放序列:例如,我們可能知道字符串長(zhǎng)度,或者有一個(gè)static不需要這種愚蠢的字符串malloc。


查看完整回答
反對(duì) 回復(fù) 2023-01-03
  • 1 回答
  • 0 關(guān)注
  • 339 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)