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
1
nifury 2022-07-29 11:34:08 +08:00
hmm 大概是 gcc 不支持__declspec(dllexport)?
能编译成 dll 不代表能编译成 so 啊 |
2
hhhhhh123 OP ```
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 ``` |
3
qbqbqbqb 2022-07-29 11:35:47 +08:00
GCC 编译器是没有__declspec(dllexport)的,建议用 ifdef 控制一下
|
5
hhhhhh123 OP @qbqbqbqb 我删除 extern "C" __declspec(dllexport) 这个了,但是出现了上面的错误, 你知道吗
|
7
qbqbqbqb 2022-07-29 11:37:40 +08:00
extern "C"不要随便删,只删__declspec(dllexport)
|
8
qbqbqbqb 2022-07-29 11:43:26 +08:00
@hhhhhh123 这个错误和 ompeval.a 这个静态库有关。一般情况下静态库和 so 动态库是不能混用的,除非静态库编译的时候加了-fPIC 参数才可以。如果可以的话就重新编译这个静态库。
|
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"))) |
10
hhhhhh123 OP |
11
yolee599 2022-07-29 12:35:25 +08:00 via Android
执行下面这个指令看看有没有导出?
nm -D <your .so file> |
12
hhhhhh123 OP @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 _ZN3omp13CombinedRangeC2EjRKSt6vectorISt5arrayIhLm2EESaIS3_EE 000000000000ad00 T _ZN3omp13CombinedRangeC2Ev 0000000000014930 T _ZN3omp13HandEvaluator10staticInitEv 00000000000164c0 R _ZN3omp13HandEvaluator11FLUSH_RANKSE 0000000000026460 B _ZN3omp13HandEvaluator11ORIG_LOOKUPE 0000000000022460 B _ZN3omp13HandEvaluator12FLUSH_LOOKUPE 00000000000147f0 T _ZN3omp13HandEvaluator14populateLookupEmjjjjjjb 还有很多这样的 , 次数超过限制所有发不出来 |
13
hhhhhh123 OP 解决了 extern "C" 我删掉了 忘记加上去了, 所以没有导出来, 加上后 重新编译 函数也能导出来了。
|
14
proxytoworld 2022-07-29 13:52:17 +08:00
|
15
proxytoworld 2022-07-29 13:52:57 +08:00
看错了,得编译 so
|
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 |