


Detailed explanation of commonly used data conversion and usage in CGO projects
This article is provided by the golang tutorial column to introduce you to the commonly used data conversion and use in CGO practical projects. I hope it will be helpful to friends in need!
Preface
You need to deploy the relevant environment and have basic knowledge points. This is not a popular science article, it is mainly for the types used in actual projects. Conversion and use, for the function call parameter transmission and reception of dynamic libraries
1. GO environment, start to support CGO
2. Install g in advance
3. Understand the syntax of GO and C
4 , it is best to know basic makefile or shell syntax (meaning I don’t understand it, I am a noob, and I can only read a rough outline) mainly because I need to use it when debugging C by myself.
If you know everything, please click on the literacy link: chai2010.cn/advanced-go-programmin...
List of basic data types
Because GO supports C language calls , so only the conversion with C is listed. As for C, it needs to be converted into C language before it can be called successfully. It should be noted that each C variable is limited to use within one package. If you want to use it across packages, please use GO to encapsulate it. Otherwise, a calling error will be prompted and the C variable cannot be found.
Data type conversion used in the project
#Go string is converted into C
C string is one character The special case of arrays, simply put, is that a character array ending with 0 is a string, so it does not belong to the basic data type.
C.CString is a standard library that calls C. It applies for new memory space and needs to call C.free to release it, otherwise memory leaks will occur.
var deviceIp string cdeviceIp := C.CString(deviceIp) defer C.free(unsafe.Pointer(cdeviceIp))
C's char * /char[] is converted into go's string
Call C's standard library C.GoString, this function will not generate new memory space , creates a copy and does not release memory space.
Convert C byte array to Go string
For example, the type of C is: BYTE sSerialNumber[SERIALNO_LEN];
The way to obtain it is to use append to add Bytes to string
serialNo := make([]byte, 0) for _, v := range sSerialNumber { if v != 0 { serialNo = append(serialNo, byte(v)) } }
Note the difference between character arrays and strings mentioned earlier.
Go string to C character array
Type: CHAR szKeyFilePath[PU_CERT_FILE_PATH_MAX];
var keyFilePath = "/home/docker/path/file.jpg" for i, b := range keyFilePath { szKeyFilePath[i] = C.CHAR(b) }
Combined Data Acquisition
When connecting to the data callback of the Huawei camera, the union type data is obtained. When it is obtained as a normal structure, the compiler will always prompt that the structure cannot be found. As a last resort, in the C code After obtaining the data of the union, convert it to the basic data type, and then call Go again. Post a code snippet to get the data from the face recognition callback. Don't worry about the context, just look at how to get the data type.
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 ;}
If this code is replaced with Go logic and read directly in Go, it will prompt that unMetaData cannot find the definition. If there are other successful reading methods, please let us know.
Call callback function in C
1. First implement the function with the same data type in Go code, and use //export to export it as a C function. If the callback is not found, , first check whether the data type is correct, and then check whether the trigger condition is met. This step is to receive the C language callback data in Go language, that is, the callback data is obtained in this function.
2. CGO calls the C function. Some colleagues said that this step can be omitted. You can just call the function in the first step directly in Go. I haven't tried it yet. The company's ancestral code is written like this, so I just follow it. used.
3. Just call it directly as a common function in GO language.
Look at the code example:
C function declaration:
typedef VOID (CALLBACK *pfRealDataCallBack)(CHAR *szBuffer, LONG lSize, VOID *pUsrData);
The code of the first step:
//export GopfRealDataCallBackfunc GopfRealDataCallBack(szBuffer *C.CHAR, lSize C.LONG, pUsrData unsafe.Pointer) { fmt.Println(szBuffer,lSize,pUsrData)}
The second step:
extern void GopfRealDataCallBack(CHAR *szBuffer, LONG lSize, void *pUsrData);void CGopfRealDataCallBack(CHAR *szBuffer, LONG lSize, void *pUsrData){ return GopfRealDataCallBack(szBuffer,lSize,pUsrData);}
The third step: C.pfRealDataCallBack(C.CGopfRealDataCallBack) needs to be declared on import C, otherwise the call will not take effect
void* and unsafe.Pointer
unsafe.Pointer is known as all Data type transfer bridges can be considered equivalent at the language level. When void* is encountered, unsafe.Pointer can be used to receive or transmit it. Conversion of specific types requires forced conversion based on the actual type. For example:
lpOutBuff := unsafe.Pointer(C.malloc(1024))
This 1024 can be modified based on the actual situation, and it is not a panacea.
结构体数组的传递
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>
The above is the detailed content of Detailed explanation of commonly used data conversion and usage in CGO projects. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Reading and writing files safely in Go is crucial. Guidelines include: Checking file permissions Closing files using defer Validating file paths Using context timeouts Following these guidelines ensures the security of your data and the robustness of your application.

How to configure connection pooling for Go database connections? Use the DB type in the database/sql package to create a database connection; set MaxOpenConns to control the maximum number of concurrent connections; set MaxIdleConns to set the maximum number of idle connections; set ConnMaxLifetime to control the maximum life cycle of the connection.

JSON data can be saved into a MySQL database by using the gjson library or the json.Unmarshal function. The gjson library provides convenience methods to parse JSON fields, and the json.Unmarshal function requires a target type pointer to unmarshal JSON data. Both methods require preparing SQL statements and performing insert operations to persist the data into the database.

The difference between the GoLang framework and the Go framework is reflected in the internal architecture and external features. The GoLang framework is based on the Go standard library and extends its functionality, while the Go framework consists of independent libraries to achieve specific purposes. The GoLang framework is more flexible and the Go framework is easier to use. The GoLang framework has a slight advantage in performance, and the Go framework is more scalable. Case: gin-gonic (Go framework) is used to build REST API, while Echo (GoLang framework) is used to build web applications.

Backend learning path: The exploration journey from front-end to back-end As a back-end beginner who transforms from front-end development, you already have the foundation of nodejs,...

The FindStringSubmatch function finds the first substring matched by a regular expression: the function returns a slice containing the matching substring, with the first element being the entire matched string and subsequent elements being individual substrings. Code example: regexp.FindStringSubmatch(text,pattern) returns a slice of matching substrings. Practical case: It can be used to match the domain name in the email address, for example: email:="user@example.com", pattern:=@([^\s]+)$ to get the domain name match[1].

Go framework development FAQ: Framework selection: Depends on application requirements and developer preferences, such as Gin (API), Echo (extensible), Beego (ORM), Iris (performance). Installation and use: Use the gomod command to install, import the framework and use it. Database interaction: Use ORM libraries, such as gorm, to establish database connections and operations. Authentication and authorization: Use session management and authentication middleware such as gin-contrib/sessions. Practical case: Use the Gin framework to build a simple blog API that provides POST, GET and other functions.

Using predefined time zones in Go includes the following steps: Import the "time" package. Load a specific time zone through the LoadLocation function. Use the loaded time zone in operations such as creating Time objects, parsing time strings, and performing date and time conversions. Compare dates using different time zones to illustrate the application of the predefined time zone feature.
