c++ 在服务器上打包 so 文件问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hhhhhh123
V2EX    C

c++ 在服务器上打包 so 文件问题

  •  
  •   hhhhhh123 2022-07-29 11:25:55 +08:00 2684 次点击
    这是一个创建于 1220 天前的主题,其中的信息可能已经有所发展或是发生改变。
    extern "C" __declspec(dllexport) float * OMP_EVAL(char* p1, char* p2, char* p3, char* p4, char* p5, char* p6, char* p7, char* p8, char* p9, char* _board, char* _dead, bool eval_or_monte_carlo ){ // 省略函数里面代码.. } 

    面这串导出代码 我在 win 本地是能编译成 dll 动态库的, 但是在服务器上面编译就报错了

    main.cpp:13:22: error: expected constructor, destructor, or type conversion before ‘(’ token 13 | extern "C" __declspec(dllexport) float * OMP_EVAL(char* p1, char* p2, char* p3, char* p4, char* p5, char* p6, char* p7, char* p8, char* p9, | ^ make: *** [Makefile:25: hongyu] Error 1 
    16 条回复    2022-07-30 21:24:32 +08:00
    nifury
        1
    nifury  
       2022-07-29 11:34:08 +08:00
    hmm 大概是 gcc 不支持__declspec(dllexport)?
    能编译成 dll 不代表能编译成 so 啊
    hhhhhh123
        2
    hhhhhh123  
    OP
       2022-07-29 11:35:31 +08:00
    ```
    g++ -O3 -std=c++11 -Wall -Wpedantic -pthread -c -o omp/CardRange.o omp/CardRange.cpp
    g++ -O3 -std=c++11 -Wall -Wpedantic -pthread -c -o omp/CombinedRange.o omp/CombinedRange.cpp
    g++ -O3 -std=c++11 -Wall -Wpedantic -pthread -c -o omp/EquityCalculator.o omp/EquityCalculator.cpp
    g++ -O3 -std=c++11 -Wall -Wpedantic -pthread -c -o omp/HandEvaluator.o omp/HandEvaluator.cpp
    ar rcs lib/ompeval.a omp/CardRange.o omp/CombinedRange.o omp/EquityCalculator.o omp/HandEvaluator.o
    g++ -O3 -std=c++11 -Wall -Wpedantic -pthread -shared -o hongyu.so main.cpp benchmark.cpp lib/ompeval.a
    /usr/bin/ld: lib/ompeval.a(HandEvaluator.o): warning: relocation against `_ZN3omp13HandEvaluator8cardInitE' in read-only section `.text.startup'
    /usr/bin/ld: /tmp/ccUEKBa8.o: relocation R_X86_64_PC32 against symbol `_ZSt4cout@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
    /usr/bin/ld: final link failed: bad value
    collect2: error: ld returned 1 exit status
    make: *** [Makefile:25: hongyu] Error 1
    ```
    qbqbqbqb
        3
    qbqbqbqb  
       2022-07-29 11:35:47 +08:00
    GCC 编译器是没有__declspec(dllexport)的,建议用 ifdef 控制一下
    hhhhhh123
        4
    hhhhhh123  
    OP
       2022-07-29 11:35:59 +08:00
    @nifury 你知道这个错误吗? 我吧 extern "C" __declspec(dllexport) 删掉了
    hhhhhh123
        5
    hhhhhh123  
    OP
       2022-07-29 11:36:23 +08:00
    @qbqbqbqb 我删除 extern "C" __declspec(dllexport) 这个了,但是出现了上面的错误, 你知道吗
    qbqbqbqb
        6
    qbqbqbqb  
       2022-07-29 11:37:01 +08:00
    @hhhhhh123 编译 so 的时候要加-fPIC 参数
    qbqbqbqb
        7
    qbqbqbqb  
       2022-07-29 11:37:40 +08:00
    extern "C"不要随便删,只删__declspec(dllexport)
    qbqbqbqb
        8
    qbqbqbqb  
       2022-07-29 11:43:26 +08:00
    @hhhhhh123 这个错误和 ompeval.a 这个静态库有关。一般情况下静态库和 so 动态库是不能混用的,除非静态库编译的时候加了-fPIC 参数才可以。如果可以的话就重新编译这个静态库。
    qbqbqbqb
        9
    qbqbqbqb  
       2022-07-29 11:51:42 +08:00   1
    如果无法重新编译静态库的话,可以考虑改符号导出。需要保证接口函数(原来的加了 dllexport 的函数)里面不能直接调用 ompeval.a 静态库里的函数。

    dllexport 在 Linux 环境的类似物是__attribute__ ((visibility ("default")))和__attribute__ ((visibility ("hidden")))。但是 GCC 默认选项是 default ,相当于默认全部 dllexport ,这里需要隐藏一些内部实现。

    有两种方法:
    第一种方法是编译加参数-fvisibility=hidden 修改为类似 Windows DLL 的默认不导出,然后在原来的 dllexport 的函数上加__attribute__ ((visibility ("default")))
    第二种方法是给用到了 ompeval.a 静态库的内部函数加__attribute__ ((visibility ("hidden")))
    hhhhhh123
        10
    hhhhhh123  
    OP
       2022-07-29 12:02:40 +08:00
    @nifury @qbqbqbqb
    @qbqbqbqb 我加了-fPIC 参数, 虽然能编译, 但是函数好像没有导出, 这个时候 应该怎么导出
    yolee599
        11
    yolee599  
       2022-07-29 12:35:25 +08:00 via Android
    执行下面这个指令看看有没有导出?
    nm -D <your .so file>
    hhhhhh123
        12
    hhhhhh123  
    OP
       2022-07-29 13:47:35 +08:00
    @yolee599 0000000000006710 T OMP_EVAL
    w _ITM_deregisterTMCloneTable
    w _ITM_registerTMCloneTable
    U _Unwind_Resume@GCC_3.0
    0000000000007c40 T _Z9benchmarkv
    000000000000b460 T _ZN3omp13CombinedRange10joinRangesERKSt6vectorIS1_ISt5arrayIhLm2EESaIS3_EESaIS5_EEm
    000000000000ad90 T _ZN3omp13CombinedRange7shuffleEv
    000000000000ae90 T _ZN3omp13CombinedRangeC1EjRKSt6vectorISt5arrayIhLm2EESaIS3_EE
    000000000000ad00 T _ZN3omp13CombinedRangeC1Ev
    000000000000ae90 T _ZN3omp13CombinedRangeC2EjRKSt6vectorIS5arrayIhLm2EESaIS3_EE
    000000000000ad00 T _ZN3omp13CombinedRangeC2Ev
    0000000000014930 T _ZN3omp13HandEvaluator10staticInitEv
    00000000000164c0 R _ZN3omp13HandEvaluator11FLUSH_RANKSE
    0000000000026460 B _ZN3omp13HandEvaluator11ORIG_LOOKUPE
    0000000000022460 B _ZN3omp13HandEvaluator12FLUSH_LOOKUPE
    00000000000147f0 T _ZN3omp13HandEvaluator14populateLookupEmjjjjjjb



    还有很多这样的 , 次数超过限制所有发不出来
    hhhhhh123
        13
    hhhhhh123  
    OP
       2022-07-29 13:49:01 +08:00
    解决了 extern "C" 我删掉了 忘记加上去了, 所以没有导出来, 加上后 重新编译 函数也能导出来了。
    proxytoworld
        14
    proxytoworld  
       2022-07-29 13:52:17 +08:00
    我用 cmake ,windows + gcc 编译成功..
    环境 windows + cmake + gcc 8.1.0 seh
    ![]( )
    proxytoworld
        15
    proxytoworld  
       2022-07-29 13:52:57 +08:00
    看错了,得编译 so
    buffzty
        16
    buffzty  
       2022-07-30 21:24:32 +08:00
    加个 LIB_API 宏定义
    #if defined WIN32 && !defined(BUFF_STATIC)
    #ifdef LIB_EXPORTS
    #define LIB_API __declspec(dllexport)
    #else
    #define LIB_API __declspec(dllimport)
    #endif
    #else
    #define LIB_API
    #endif
    #ifdef __cplusplus
    extern "C" {
    #endif
    LIB_API void libFn1();

    #ifdef __cplusplus
    }
    #endif
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2791 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 13:06 PVG 21:06 LAX 05:06 JFK 08:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86