摘要:c++呼叫go方法時,字串引數的記憶體管理需要由go側進行深度值拷貝。
現象在乙個app技術專案中,子程序按請求載入go的servicemodule,將需要拉起的servicemodule資訊傳遞給go的loader,存在c++呼叫go方法,傳遞字串的場景。
方案驗證時,發現有奇怪的將std::string物件的內容傳遞給go方法後,在go方法協程中取到的值與預期不一致。
經過一段時間的分析和驗證,終於理解問題產生的原因並給出解決方案,現分享如下。
背景知識
原理及解釋
通過**示例方式解釋具體現象及原因,詳見注釋
c++側**:
//// created by w00526151 on 2020/11/5.
//#include
#include
#include
#include "libgoloader.h"
/*** 構造gostring結構體物件
* @param p
* @param n
* @return
*/gostring buildgostring(const char* p, size_t n) _gostring_;
//typedef _gostring_ gostring;
return ;
}
int main()
pause();
}go側**:
package main
import "c"
import (
"fmt"
"time"
)
func printingo(p0 string, p1 string, p2 string)
//export loadmodule
func loadmodule(name string, version string, location string) int
go側**通過-buildmode=c-shared的方式生成libgoloader.so及libgoloader.h供c++編譯執行使用
go build -o libgoloawww.cppcns.comder.so -buildmode=c-shared .
程式執行結果:
test send string to go in c++
in c++ tmpstr: 0x7fffe1fb93f0, tmpstr: /tmp/udsgateway-netconftemplateservice, tmpstr.size:38
# 將c++的指標傳給go,一開始列印都是ok的
in go loadmodule,first param is /tmp/udsgateway-netconftemplateservice second param is /tmp/udsgateway-netconftemplateservice third param is /tmp/udsgateway-netconftemplateservice
# 在c++中,將指標指向的內容修改,或者刪掉指標
in c++ change tmpstr and delete newstrptr, new tmpstr: 0x7fffe1fb93f0, tmpstr: new string, tmpstr.size:10
# 在go中,引數1、引數2對應的go string變數都受到了影響,引數3由於做了深度拷貝,沒有受到影響。
in go function, p0:new string eway-netconftemplateservice size 38, p1: &n程式設計客棧bsp; p��� netconftemplateservice size 38, p2:/tmp/udsgateway-netconftemplateservice size 38
結論在c++**中,任何對成員p的char*指標的操作,都將直接影響到go中的string物件的值。
只有通過單獨的記憶體空間開闢,進行獨立記憶體管理,才可以避免c++中的指標操作對go的影響。
ps:不在c++中進行記憶體申請釋放的原因是c++無法感知go中何時才能真的已經沒有物件引用,無法找到合適的時間點進行記憶體釋放。
C 呼叫Dll 傳遞字串指標引數
最近用c 寫乙個小軟體,要呼叫vc寫的dll,傳遞引數給dll,由於是非託管 所以呼叫起來有點麻煩,要把引數轉換成非託管 的指標引數,然後再傳遞給dll using system.runtime.interopservices 操作dll的類空間 class cgicomindex marshal....
go字串拼接方法
go 語言中的字串是唯讀的 拼接方式 這種方式是我在寫golang經常用的方式,go語言用 拼接,php使用.拼接,不過由於golang中的字串是不可變的型別,因此用 連線會產生乙個新的字串對效率有影響。go語言中文文件 www.topgoer.com func main sprintf函式 s1 ...
c函式傳遞字串
把具有相同型別的若干變數按有序的形式組織起來,這些按序排列的同類資料元素的集合稱為陣列。按陣列元素的型別不同,陣列又可分為數值陣列 字元陣列 指標陣列 結構陣列等各種類別,因此,字元陣列是陣列的一種。字元陣列實際上是一系列字元的集合,也就是字串 string 由此可得 在函式中傳遞乙個字串與傳遞乙個...