前言
编译项目时有时会碰到c/c++混合编译的问题,本文使用生成动态链接库的方式,解决c/c++混合编译的问题,作者本人是因为编译avx512指令集遇到,所以以avx512指令集编译为例
提示:以下是本篇文章正文内容,下面案例可供参考
一、生成动态链接库
1.g++编译生成动态链接库
编译avx512指令集库:
g++ mmse.c -fPIC -shared -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -o libmmse.so -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D_LARGE_FILE_SOURCE -mavx512bw -mavx512vl -mavx512f -mavx512cd -mavx512dq -ldl
mmse.c为待编译为动态库的函数,动态库为libmmse.so
二、项目加载动态库
1.手动加载
代码如下(示例):
#include<stdio.h>
#include<stdlib.h>
#include<dlfcn.h>
#define N_FULLBAND_SC_MU1_100MHZ (3276)
#define N_MAX_CP_MU1_100MHZ (352)
#include <immintrin.h>
int16_t gCeTimeOffsetScCpMu1[N_FULLBAND_SC_MU1_100MHZ*(N_MAX_CP_MU1_100MHZ*2+1)*2];
typedef void (*fun_c)(int16_t **, const int16_t,
const int16_t, const int16_t, const int16_t,
int16_t *, int16_t *,
const int16_t, const int16_t, const int16_t, const int16_t);
void (*dmrs_ce_ta_est_5gnr)(int16_t * pLS[], const int16_t nRx,
const int16_t nDmrsSC, const int16_t nStartSC, const int16_t nType,
int16_t * pTimeOffset, int16_t * pTableTimeOffsetScCp,
const int16_t nFftSize, const int16_t nMaxCp, const int16_t nFullBandSc, const int16_t nTaCompEnable);
int main()
{
int16_t *pLS[8][16] = {NULL};
int16_t nDmrsSC = 4 * 6;
int16_t nStartSC = 0 * 12;
int16_t nDelta[8] = {0};
int16_t ta=0;
int16_t *pCeTaFftShiftScCp = gCeTimeOffsetScCpMu1;
pLS[0][0]=(int16_t*)_mm_malloc(61440*4,64);
void * handle=dlopen("/usr/lib/libmmse.so",RTLD_LAZY);
if(!handle)
{
printf("error handle %p\n",handle);
}
printf("ld succeed\n");
dmrs_ce_ta_est_5gnr=(fun_c)dlsym(handle,"dmrs_ce_ta_est_5gnr");
if(!dmrs_ce_ta_est_5gnr)
{
printf("addr error dmrs_ce_ta_est_5gnr %p\n",(void*)dmrs_ce_ta_est_5gnr);
}
printf("fun addr succeed %p\n",(void*)dmrs_ce_ta_est_5gnr);
dmrs_ce_ta_est_5gnr(pLS[0], 1, nDmrsSC, nStartSC+nDelta[0], 1,
&ta, pCeTaFftShiftScCp,
4096, N_MAX_CP_MU1_100MHZ, N_FULLBAND_SC_MU1_100MHZ, 0);
_mm_free(pLS[0][0]);
printf("\n------mmse------\n");
}
dlopen dlsym链接动态库
2.动态库链接不上
如果动态库是纯c++代码,连接时只加函数名会出现连接不上的问题,具体问题如下:nm -D看一下动态库的符号表就会发现问题:
root@us:/home/mmse# nm -D libmmse.so
U atan2f
0000000000205038 B __bss_start
w __cxa_finalize
0000000000205038 D _edata
0000000000205280 B _end
0000000000004a40 T _fini
w __gmon_start__
00000000000006b8 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000205080 B kStride3permFirst
00000000002050c0 B kStride3permSecond
0000000000205100 B m512Neg_I
U __stack_chk_fail
0000000000000a3b T _Z19dmrs_ce_ta_est_5gnrPPsssssS_S_ssss
0000000000004a10 W _ZSt5atan2ff
root@us:/home/mmse#
可以看出c++编译的符号表和函数名是不统一的,可能和c++函数能重载有关,解决方法让动态库以“c”编译。
#ifdef __cplusplus
extern "C"{
#endif
\\\\\\\\\\\
#ifdef __cplusplus
}
#endif
符号表变化
root@us:/home/mmse# nm -D libmmse.so
U atan2f
0000000000205038 B __bss_start
w __cxa_finalize
0000000000000a2b T dmrs_ce_ta_est_5gnr
0000000000205038 D _edata
0000000000205280 B _end
0000000000004a30 T _fini
w __gmon_start__
00000000000006a8 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000205080 B kStride3permFirst
00000000002050c0 B kStride3permSecond
0000000000205100 B m512Neg_I
U __stack_chk_fail
0000000000004a00 W _ZSt5atan2ff
root@us:/home/mmse#
总结
本文只是提供了一个生成动态库的方法,有其它方式欢迎分享。