在c ++中加载共享库会导致分段错误

Mag*_*ick 1 c++ valgrind

我正在学习c ++,并正在尝试在linux上加载共享库(.so).

运行以下代码时出现分段错误.

当我尝试使用valgrind运行控制台应用程序时,我得到以下内容:

valgrind ./TestLoadSo --leak-check=full -v
==26828== Memcheck, a memory error detector
==26828== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==26828== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==26828== Command: ./TestLoadSo --leak-check=full -v
==26828== 
!!!Hello World!!!
==26828== Jump to the invalid address stated on the next line
==26828==    at 0x0: ???
==26828==    by 0x53E63F0: (below main) (libc-start.c:291)
==26828==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==26828== 
==26828== 
==26828== Process terminating with default action of signal 11 (SIGSEGV)
==26828==  Bad permissions for mapped region at address 0x0
==26828==    at 0x0: ???
==26828==    by 0x53E63F0: (below main) (libc-start.c:291)
==26828== 
==26828== HEAP SUMMARY:
==26828==     in use at exit: 3,126 bytes in 9 blocks
==26828==   total heap usage: 13 allocs, 4 frees, 76,998 bytes allocated
==26828== 
==26828== LEAK SUMMARY:
==26828==    definitely lost: 0 bytes in 0 blocks
==26828==    indirectly lost: 0 bytes in 0 blocks
==26828==      possibly lost: 0 bytes in 0 blocks
==26828==    still reachable: 3,126 bytes in 9 blocks
==26828==         suppressed: 0 bytes in 0 blocks
==26828== Rerun with --leak-check=full to see details of leaked memory
==26828== 
==26828== For counts of detected and suppressed errors, rerun with: -v
==26828== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
[1]    26828 segmentation fault (core dumped)  valgrind ./TestLoadSo --leak-check=full -v
Run Code Online (Sandbox Code Playgroud)

C++主类

extern "C" typedef char* (*helloWorld_t)();

int main() {

    void* handle = dlopen("./libMyLib.dll.so", RTLD_LAZY);

    if (!handle) {
     cerr << "Cannot open library: " << dlerror() << '\n';
     return 1;
     }
    helloWorld_t hello = (helloWorld_t)dlsym( handle, "helloWorld" );
    const char * tmp = hello();
     printf("\n%s",tmp);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

外部功能是:

extern "C++" char* helloWorld() {
    char str[25];
    strcpy(str, "HelloWorld");
}
Run Code Online (Sandbox Code Playgroud)

如果我使用extern "C"我得到编译错误:

error: conflicting declaration of ‘char* helloWorld()’ with ‘C’ linkage
 extern "C" char* helloWorld() {
Run Code Online (Sandbox Code Playgroud)

我真的不清楚我哪里出错了.

n. *_* m. 5

函数不能同时具有C和C++链接,函数指针类型必须与其目标函数的链接匹配.

你不能dlsymextern "C++"它的朴实无华的名字的功能.您必须extern "C"在两种情况下使用(推荐),或者extern "C++"在整个过程中使用,并将字符串替换为dlsym(handle, "helloWorld")函数的错位名称(推荐).

dlsym如果它返回一个空指针,请务必检查结果并报告错误(使用dlerror()就像你所做的那样dlopen).

不要使用字符数组或指针来表示字符串.有一个字符串类型,叫做std::string.

最后但并非最不重要的是,总是进行编译,-Wall -Werror因此void会捕获一些实际上不返回值的非函数.