Golang调用C函数-返回结构体

2023-02-23

golang仅支持c函数调用

C函数实例

目录结构

.
├── CMakeLists.txt
├── includes
│   └── library.h
└── src
    └── library.cpp

源码

library.h


#ifndef PDVCLIBRARY
#define PDVCLIBRARY

#ifdef __cplusplus
extern "C"{
#endif
//结构体
typedef struct TestStruc{
    int ID;
    char *sName;
    int nbChild;

} TS;

extern int testFunc();

extern char *testString();
TS *testStruct();


#ifdef __cplusplus
}
#endif

#endif

library.cpp


#include "library.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>


int testFunc()
{
    unsigned int sum = 0;
    for (size_t i = 0; i < 100; i++)
    {
        for (size_t j = 0; j < 100; j++)
        {
            for (size_t k = 0; k  < 1000000; k++)
            {
                sum += k;
            }            
        }           
    }
    return sum;    
}

char *testString()
{
    char *str = (char *)malloc(13*sizeof(char));
    sprintf(str,"%s","Hello world!");
    return str;
}

TS *testStruct()
{
    TS *pNewStruct = (struct TestStruc*)malloc(sizeof(struct TestStruc));
    pNewStruct->ID = 10;
    pNewStruct->sName = (char *)malloc(13*sizeof(char));
    sprintf(pNewStruct->sName,"%s","Hello world!");

    return pNewStruct;

    //或者
    /*

    TS testStruct()
    {
        TS NewStruct ;
        NewStruct.ID = 10;
        NewStruct.sName = (char *)malloc(13*sizeof(char));
        sprintf(NewStruct.sName,"%s","Hello world!");

        return NewStruct;

    }

    */
}


CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(CLibiary VERSION 0.1 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 11)


include_directories(
    ./includes/
)

FILE(GLOB CLibiary_Header "./includes/*.h")
FILE(GLOB CLibiary_SRC "./src/*.cpp")

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build/libs/$<0:>")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build/bin/$<0:>")

#静态库
set(CLibiary_Target_STATIC "CLibiarySTATIC")
add_library(${CLibiary_Target_STATIC} STATIC  ${CLibiary_Header} ${CLibiary_SRC})
target_link_libraries(${CLibiary_Target_STATIC} -Wall -pthread)

#动态库
set(CLibiary_Target_SHARE "CLibiarySHARED")
add_library(${CLibiary_Target_SHARE} SHARED  ${CLibiary_Header} ${CLibiary_SRC})
target_link_libraries(${CLibiary_Target_SHARE} -Wall -pthread)


file(COPY ./includes/ DESTINATION ./build/includes/)

静态库(动态库方式见上一篇文章)

目录结构

注释同动态库目录结构

.
├── go.mod
├── libCLibiarySTATIC.a
├── library.h
├── main.go

main.go


package main

/*
#include "library.h"
#include <stdlib.h>
#cgo CFLAGS: -I.
#cgo LDFLAGS: -L. -lCLibiarySTATIC -lstdc++
*/
import "C"
import (
	"fmt"
	"unsafe"
)

func main() {
	//调用C函数
	result := C.testStruct()
	fmt.Println(result.ID)
	sName := C.GoString(result.sName)
	C.free(unsafe.Pointer(result.sName))
	fmt.Println(sName)
}