c go使用笔记

go c 数据传输

func Opus2Aac(opusData []byte) []byte {

    pushURL := C.CString(self.dst_url) // 会创建一个c内存. 手动要释放
	defer C.free(unsafe.Pointer(pushURL)) 

	srcp := (*C.uchar)(unsafe.Pointer(&opusData[0]))
	srcLen := (C.int)(len(opusData))

	dst := make([]byte, 2048)   // go 申请内存, c申请参考下面的
	dstp := (*C.uchar)(unsafe.Pointer(&dst[0]))

	var retSize C.int

    // void Opus2aac(AudioTranscode* at, unsigned char* src, int len, unsigned char* dst, int* retSize);
	C.Opus2aac(self.opus_to_aac_ctx, srcp, srcLen, dstp, &retSize)
	rett := (int)(retSize)
	if rett <= 0 {
		return nil
	}
	return dst[:rett]
}

// c 申请内存 go 释放 可能会内存泄漏 

src, err := hex.DecodeString(line)
if err != nil || len(src) <= 0 {
	fmt.Println("err:", err)
	return
}


srcp := (*C.uchar)(unsafe.Pointer(&src[0]))
srcLen := (C.int)(len(src))

ts := (C.int)(n * 100)
var dst uintptr
dstp := (**C.uchar)(unsafe.Pointer(&dst)) // 用**, c malloc

ret := C.transcode(at, srcp, srcLen, dstp, ts)
rett := (int)(ret)

// uintptr 转 slice 
outputData := struct {
	addr uintptr
	len  int
	cap  int
}{dst, rett, rett}

outputslice := *(*[]byte)(unsafe.Pointer(&outputData))
outputImgData := make([]byte, rett)
copy(outputImgData, outputslice)
C.free(unsafe.Pointer(dst))

fmt.Printf("go==ret=%d==%x", len(outputslice), outputslice[:])

go 调 c, c 调 go

  • c文件头
#pragma once

#ifdef __cplusplus

 extern "C" {
 #endif

int func1();

#ifdef __cplusplus
 }
#endif
  • c++ 文件头
#pragma once

#ifdef __cplusplus

 extern "C" {
 #endif

int test();

#ifdef __cplusplus
 }
#endif

rm libtrans.a

g++ -o tmp_trans.o -c trans_audio.cpp
gcc -o tmp_call.o -c call_cpp.c

ar -crs  libtrans.a tmp_call.o tmp_trans.o


rm tmp_trans.o
rm tmp_call.o
  • go文件
/*

#cgo CFLAGS: -Iinclude

#cgo LDFLAGS: -L/usr/local/Cellar/ffmpeg/3.4.1/lib -lavdevice -lavformat -lavfilter -lavcodec -lswresample -lswscale -lavutil

#include"trans.h"
*/
import "C"

c调用go的日志库

  • .go文件, 注释必须
    //export LogPrint
    func LogPrint(info *C.char) {
    	infoString := C.GoString(info)
    	log.Info(infoString)
    }
    
  • .h 文件
    typedef void (*CGO_LOGPRINT)( const char *info);
    extern void LogPrint( char *);
    
  • .c文件
    CGO_LOGPRINT c_logprint = LogPrint;
    
    void cgoLogPrint(const char* szBuffer) {
      c_logprint(szBuffer);
      return;
    }
    
    void cgoLogPrintf(const char* fmt, ...) {
      char szBuffer[512];
      va_list vlist;
    
      va_start(vlist, fmt);
      vsprintf(szBuffer, fmt, vlist);
      va_end(vlist);
    
      c_logprint(szBuffer);
    }
    
  • 编译 go build
  • c日志格式化
    #define PPrint(fmt) \
      cgoLogPrintf("[%s/%s:%d] " fmt, __FILE__, __FUNCTION__, __LINE__)
    
    #define PPrintf(fmt, ...) \
      cgoLogPrintf("[%s/%s:%d] " fmt, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值