この記事は、golang のチュートリアル コラムから提供され、CGO の実践プロジェクトでよく使用されるデータ変換と使用方法を紹介するものです。必要!
関連する環境をデプロイし、基本的な知識を習得する必要があります。これは一般的な科学記事ではなく、主に実際のプロジェクトで使用される種類のものです。 . 動的ライブラリの関数呼び出しパラメータ送受信のための変換と利用
1. GO 環境、CGO のサポート開始
2. 事前に g をインストール
3. GO と C## の構文を理解する#4 、主に C を自分でデバッグするときに使用する必要があるため、基本的な makefile またはシェル構文を知っておくのが最善です (つまり、私は理解できません。初心者で、大まかな概要しか読めません)。 ## すべてを知っている場合は、リテラシー リンクをクリックしてください:chai2010.cn/advanced-go-programmin...
プロジェクトで使用されるデータ型変換
var deviceIp string cdeviceIp := C.CString(deviceIp) defer C.free(unsafe.Pointer(cdeviceIp))
C の char * /char[] は go の string に変換されます
C バイト配列を Go 文字列に変換します
serialNo := make([]byte, 0) for _, v := range sSerialNumber { if v != 0 { serialNo = append(serialNo, byte(v)) } }
文字列を C 文字配列に移動
var keyFilePath = "/home/docker/path/file.jpg" for i, b := range keyFilePath { szKeyFilePath[i] = C.CHAR(b) }
結合データ取得
void CGopfFaceSnapCallBack(CHAR *szBuffer, LONG lSize, void *pUsrData) { PU_META_DATA *pstMetaData = 0; int ret = Wrapper_IVS_User_GetMetaData(szBuffer, lSize, TARGET, &pstMetaData); if (ret == PU_FALSE ){ return ; } PU_UserData *pstMetaUserData = pstMetaData->pstMetaUserData; char name[100]={0}; char cardID[100]={0}; for(UINT uIndex = 0; uIndex usValidNumber; ++uIndex){ //printf("pstMetaData eType : %x\n", pstMetaUserData[uIndex].eType); if (pstMetaUserData[uIndex].eType == FACE_INFO){ strcpy(cardID, pstMetaUserData[uIndex].unMetaData.stFaceInfo.cardID); strcpy(name, pstMetaUserData[uIndex].unMetaData.stFaceInfo.name); printf("GopfFaceSnapCallBack unMetaData.stFaceInfo cardID : %s\n", pstMetaUserData[uIndex].unMetaData.stFaceInfo.cardID); printf("GopfFaceSnapCallBack unMetaData.stFaceInfo name : %s\n", pstMetaUserData[uIndex].unMetaData.stFaceInfo.name); GopfFaceSnapCallBack(pstMetaUserData[uIndex].unMetaData.stFaceInfo.cardID,pUsrData); break ; } } Wrapper_IVS_User_FreeMetaData(&pstMetaData); return ;}このコードを Go ロジックに置き換えて Go で直接読み取ると、unMetaData が定義を見つけられないというメッセージが表示されます。他に成功する読み取り方法があれば、お知らせください。
C
2. CGO は C 関数を呼び出します。一部の同僚は、このステップは省略できると言っています。最初のステップの関数を Go で直接呼び出すだけで済みます。私はまだ試していません。会社の祖先のコードは次のように書かれています。これをフォローするだけです。
3. GO 言語の共通関数として直接呼び出すだけです。
コード例を見てください:
C 関数宣言:
typedef VOID (CALLBACK *pfRealDataCallBack)(CHAR *szBuffer, LONG lSize, VOID *pUsrData);最初のステップのコード:
//export GopfRealDataCallBackfunc GopfRealDataCallBack(szBuffer *C.CHAR, lSize C.LONG, pUsrData unsafe.Pointer) { fmt.Println(szBuffer,lSize,pUsrData)}2 番目のステップ:
extern void GopfRealDataCallBack(CHAR *szBuffer, LONG lSize, void *pUsrData);void CGopfRealDataCallBack(CHAR *szBuffer, LONG lSize, void *pUsrData){ return GopfRealDataCallBack(szBuffer,lSize,pUsrData);}3 番目のステップステップ: C.pfRealDataCallBack(C.CGopfRealDataCallBack) をインポート C で宣言する必要があります。宣言しない場合、呼び出しは有効になりません
lpOutBuff := unsafe.Pointer(C.malloc(1024))この 1024 は実際の状況に基づいて変更できますが、万能薬ではありません。
results := (*C.struct_name)(C.malloc(C.size_t(C.sizeof_struct_name * C.int(resLen)))) defer C.free(unsafe.Pointer(results))
struct_name换成具体的结构体名称,申请了空间要释放,GO检测不到C的部分。
for i := 0; i <p>struct_name换成具体的结构体名称,uintptr是元素内存地址,根据偏移量获取元素。<code>go for i := 0; i <span class="rm-link-color"> </span> </code></p><p class="meta" style="margin: 35px 0px;"><em class="icon tags"></em></p>
以上がCGO プロジェクトでよく使用されるデータ変換と使用方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。