在c+中加载共享库+;导致分割错误的原因 我正在学习C++,并且在Linux上加载共享LIB(.so)。

在c+中加载共享库+;导致分割错误的原因 我正在学习C++,并且在Linux上加载共享LIB(.so)。,c++,valgrind,C++,Valgrind,当我运行下面的代码时,我遇到了一个分段错误 当我尝试使用valgrind运行console应用程序时,我得到以下结果: 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

当我运行下面的代码时,我遇到了一个分段错误

当我尝试使用valgrind运行console应用程序时,我得到以下结果:

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
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;
}
如果我使用
extern“C”
我会得到一个编译错误:

error: conflicting declaration of ‘char* helloWorld()’ with ‘C’ linkage
 extern "C" char* helloWorld() {

我真的不清楚我错在哪里dlsym函数未加修饰的名称来定义
extern“C++”
函数。您必须在两种情况下都使用
extern“C”
(推荐),或者在整个过程中使用
extern“C++”
,并将
dlsym(handle,“helloWorld”)
中的字符串替换为您函数的损坏名称(不推荐)

始终检查
dlsym
的结果,如果返回空指针,则报告错误(使用
dlerror()
就像您对
dlopen
所做的那样)

不要使用字符数组或指针来表示字符串。字符串有一种类型,称为


最后但并非最不重要的是,总是用<代码> -Walth-WError < /C>编译,所以将不会捕获不返回值的非->代码> Value>代码>函数。

< P>函数不能同时具有C和C++链接,函数指针类型必须与目标函数的链接匹配。 您不能用
dlsym
函数未加修饰的名称来定义
extern“C++”
函数。您必须在两种情况下都使用
extern“C”
(推荐),或者在整个过程中使用
extern“C++”
,并将
dlsym(handle,“helloWorld”)
中的字符串替换为您函数的损坏名称(不推荐)

始终检查
dlsym
的结果,如果返回空指针,则报告错误(使用
dlerror()
就像您对
dlopen
所做的那样)

不要使用字符数组或指针来表示字符串。字符串有一种类型,称为

最后但并非最不重要的一点是,始终使用
-Wall-Werror
进行编译,这样就可以捕捉到诸如非
void
函数之类实际上不返回值的情况。

这里有许多问题:

extern "C++" char* helloWorld() {
    char str[25];
    strcpy(str, "HelloWorld");
}
它应该使用
“C”
链接。它应该会返回一些东西。它将字符串复制到局部变量,因此返回时值会丢失。所以可能

extern "C" char* helloWorld() {
    static char str[25]; // will keep its value accross calls, not thread safe
    return strcpy(str, "HelloWorld"); // return pointer to start of str
}
请注意,多个调用都返回相同的静态缓冲区。如果您需要副本,您需要让调用者提供一个缓冲区,或者返回分配了
malloc

的缓冲区。这里有很多问题:

extern "C++" char* helloWorld() {
    char str[25];
    strcpy(str, "HelloWorld");
}
它应该使用
“C”
链接。它应该会返回一些东西。它将字符串复制到局部变量,因此返回时值会丢失。所以可能

extern "C" char* helloWorld() {
    static char str[25]; // will keep its value accross calls, not thread safe
    return strcpy(str, "HelloWorld"); // return pointer to start of str
}

请注意,多个调用都返回相同的静态缓冲区。如果您需要副本,您需要让调用方提供一个缓冲区,或者返回分配给malloc的缓冲区

“helloWorld”函数的实现是什么?还可以使用-O0编译您的程序,以便从valgrind获得更好的信息。
跳转到下一行所述的无效地址。
中似乎没有helloWorld符号。您不应该使用
extern“C”
而不是
extern“C++”
?而且您的外部helloWorld不会返回任何内容。如果您确实有
return str
,那么这将是一个问题-您不应该返回指向堆栈变量的指针。您应该在可执行文件之前传递valgrind参数,即valgrind--leak check=full-v./testloads“helloWorld”函数的实现是什么?还可以使用-O0编译您的程序,以便从valgrind获得更好的信息。
跳转到下一行所述的无效地址。
中似乎没有helloWorld符号。您不应该使用
extern“C”
而不是
extern“C++”
?而且您的外部helloWorld不会返回任何内容。如果您确实有
return str
,那么这将是一个问题-您不应该返回指向堆栈变量的指针。您应该在可执行文件之前传递valgrind参数,即valgrind--leak check=full-v./TestLoadSoThanks,这很有帮助。谢谢,这很有帮助。