GO/C语言直接调用C++ 库简单方法

GO语言调用C++ 库最好用的还是需要用swig来做个中转库,会把相关的类给你转换好,但有时如果只是调用C++写的一些函数,不是类,就可以不要中转,
如在CTP开发过程中,用到了DataCollect的库,头文件如下:
 

#ifndef  DATA_COLLECT_H
#define  DATA_COLLECT_H

///获取AES加密和RSA加密的终端信息 pSystemInfo的空间需要调用者自己分配 至少270个字节
/// macOS 返回值定义
/* 返回的int值 不为0 表示采集信息有误 具体哪个采集项有问题需要做如下判断
从低位开始分别标示 终端信息 -> CPU序列号
返回值 & (0x01 << 0) 不为0 表示终端类型未采集到
返回值 & (0x01 << 1) 不为0 表示 信息采集时间获取异常
返回值 & (0x01 << 2) 不为0 表示ip 获取失败  (采集多个相同类型信息的场景有一个采集到 即表示采集成功)
返回值 & (0x01 << 3) 不为0 表示mac 获取失败
返回值 & (0x01 << 4) 不为0 表示 设备名 获取失败
返回值 & (0x01 << 5) 不为0 表示 操作系统版本 获取失败
返回值 & (0x01 << 6) 不为0 表示 硬盘序列号 获取失败
返回值 & (0x01 << 7) 不为0 表示 CPU序列号 获取失败
*/

int CTP_GetSystemInfo(char* pSystemInfo, int& nLen);

///获取没有AES加密的终端信息
int CTP_GetSystemInfoUnAesEncode(char* pSystemInfo, int& nLen);


//版本号格式
//Sfit + 生产还是测试秘钥(pro/tst) + 秘钥版本 + 编译时间 + 版本(内部)

const char * CTP_GetDataCollectApiVersion(void);


#endif

这个头跟C没什么区别,如果我们直接#include 又不能调用,因为C与C++ 的库的实际函数名引用是不一样的,我们用nm看一下(头文件只用到CTP,这里过滤一下CTP):

这里就跟c++的头定义不一样了,不过他们的参数返回值是一样的,这样可以直接替换上这里的名称就可以用了,如:
_Z28CTP_GetSystemInfoUnAesEncodePcRi 就是 GetSystemInfoUnAesEncode 

那c代码调用就可以直接这样写


    char *result = (char *)malloc(270); // 分配堆内存
    int ret = _Z28CTP_GetSystemInfoUnAesEncodePcRi(result, length);
    if (ret == 0) {
        result[*length] = '\0';
        return result; // 返回指向堆内存的指针
    }
    free(result); // 错误时释放内存

GO用cgo 也是可以直接调用的:
来个完整调用例子:
 

package main

/*
#cgo LDFLAGS: -fPIC -L. -F/lib/lib-6.7 -Wl,-rpath,/lib/lib-6.7 -lctpgo -framework MacDataCollect  -framework CoreFoundation -framework CoreFoundation  -framework IOKit  -framework Foundation
#cgo CPPFLAGS: -fPIC -I./ -I./include -g
#cgo CFLAGS: -fPIC -I./ -I./include -g
#include "stdio.h"
#include "stdlib.h"
extern int _Z28CTP_GetSystemInfoUnAesEncodePcRi(char* pSystemInfo, int* nLen);

//重命令一个,相当于转换
char* CTP_GetSystemInfoUnAesEncode(int *length){
    char *result = (char *)malloc(270); // 分配堆内存
    int ret = _Z28CTP_GetSystemInfoUnAesEncodePcRi(result, length);
    if (ret == 0) {
        result[*length] = '\0';
        return result; // 返回指向堆内存的指针
    }
    free(result); // 错误时释放内存
    return NULL;
}

*/
import "C"

//GO 包一个
func GetSystemInfoUnAesEncode() (string, int, error) {
	var length C.int
	result := C.CTP_GetSystemInfoUnAesEncode(&length)

	if result != nil {
		//error for object 0x16ba266da: pointer being freed was not allocated
		//defer C.free(unsafe.Pointer(result)) // 使用C.free来释放内存

		// 将C字符串转换为Go字符串
		goStr := C.GoStringN(result, C.int(length))
		//println(goStr)
		return goStr, int(length), nil
	}
	return "", 0, nil
}


func main(){

  str, l, err := GetSystemInfoUnAesEncode()
  if err == nil {
	println(l, len(str))
  }

}

一个文件就行

源代码上GITHUB:

 https://github.com/pinke/data_collect_go.git
 

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值