C/C++linux动态库的加载

静态加载,编译时加载动态库

so.h

#ifndef __SO_H__
#define __SO_H__

#define DLL_PUBLIC __attribute__ ((visibility("default")))

extern "C" {
DLL_PUBLIC  void  test();
int   test2(int _v);
}

class foo
{
private:
int i ;
public:
        foo(int i){
        i = 3;}
        ~foo(){};
public:
DLL_PUBLIC   void a();
    int  b(int _v);
};
#endif

so.cpp

#include <stdio.h>
#include "so.h"


void  test()
{
    printf("test\n");
}


int  test2(int _v)
{
    return _v*_v;
}


void  foo::a()
{
    printf("foo::a()\n");
}

int  foo::b(int _v)
{
    return _v*_v;
}

main.cpp

 #include <stdio.h>
 #include "so.h"

 int main(int argc, char** argv)
 {
     test();
     printf("test2: %d\n", test2(3));

     foo f(1);
     f.a();
     printf("foo::b: %d\n", f.b(2));

     return 0;
 }
~                 

编译动态库

g++ -shared so.cpp -fPIC -o libtest.so

main.cpp 加载动态库

g++ main.cpp libtest…so -o main
或者
g++ main.cpp -L ./ test - o main //注意 动态库路径后面要有空格

用nm命令查看动态库的函数和类接口的导出情况
在这里插入图片描述
linux 下是默认到处的,可以设置不默认导出
在so.h中定义#define DLL_PUBLIC attribute ((visibility(“default”)))
在需要到处的接口中加上这个宏,编译时动态库时加上这个

g++ -shared -o libtest.so -fPIC -fvisibility=hidden so.cpp
在用nm查看动态库导出情况
在这里插入图片描述
发现只导出了用DLL_PUBLIC修饰的函数
在这里插入图片描述
测试程序也不能正常编译了

动态库的动态加载

#include <iostream>
#include <stdio.h>
#include <dlfcn.h>
using namespace std;

typedef int  (*type_pSo_TLGI)(int ) ;
int main()
{
    void *pSo_handle = NULL;

    pSo_handle = dlopen("./libtest.so", RTLD_LAZY);
    if (!pSo_handle)
    {
        cout<<"can't open .so"<<endl;
        cout<<"dlopen - "<<dlerror()<<endl;
        return -1;
    }

    type_pSo_TLGI pSo_TLGI = (type_pSo_TLGI)dlsym(pSo_handle,"test2");
    if (!pSo_TLGI)
    {
        cout<<"can't cast function"<<endl;
        fprintf(stderr, "%s\n", dlerror());
        //printf("error %s\n",stderr);
        return -1;
    }

    int i  = pSo_TLGI(2);
    printf("i %d\n",i);

        return 0;
}

注意,g++将目标文件编译成动态库时如果没有用extern "c"修饰函数,g++编译器会在函数的符号上加上一些特殊的符号,在调用dlsym函数时需要用nm命令查看函数的正确符号
在这里插入图片描述
T 后面的就是函数的符号

需要这样才能正确加载

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态链接库是一种可重定位的二进制文件,它包含了一些可供其他程序调用的函数或数据。在 Windows 平台上,动态链接库采用 .dll 后缀名,而在 Linux 平台上则采用 .so 后缀名。在本文中,我们将介绍如何使用 MFC 调用 C 语言编写的动态链接库。 # 创建动态链接库 在 Windows 平台上,可以使用 Visual Studio 创建动态链接库。下面是一个简单的示例: ```c // mydll.h #ifndef MYDLL_H #define MYDLL_H #ifdef __cplusplus extern "C" { #endif __declspec(dllexport) int add(int a, int b); #ifdef __cplusplus } #endif #endif // MYDLL_H // mydll.c #include "mydll.h" int add(int a, int b) { return a + b; } ``` 这个动态链接库包含一个 add 函数,可以对两个整数求和。 # 调用动态链接库 在 MFC 项目中调用动态链接库,需要进行以下几个步骤: 1. 定义一个函数指针类型,指向动态链接库中的函数。 ```c++ typedef int (*AddFunc)(int, int); ``` 2. 加载动态链接库。 ```c++ HINSTANCE hinstLib = LoadLibrary(TEXT("mydll.dll")); if (hinstLib == NULL) { AfxMessageBox(TEXT("Failed to load library.")); return; } ``` 3. 获取动态链接库中的函数地址。 ```c++ AddFunc addFunc = (AddFunc)GetProcAddress(hinstLib, "add"); if (addFunc == NULL) { AfxMessageBox(TEXT("Failed to get function address.")); FreeLibrary(hinstLib); return; } ``` 4. 调用动态链接库中的函数。 ```c++ int result = addFunc(1, 2); CString str; str.Format(TEXT("1 + 2 = %d"), result); AfxMessageBox(str); ``` 5. 卸载动态链接库。 ```c++ FreeLibrary(hinstLib); ``` 完整的 MFC 代码示例: ```c++ typedef int (*AddFunc)(int, int); void CMyDlg::OnButton1() { HINSTANCE hinstLib = LoadLibrary(TEXT("mydll.dll")); if (hinstLib == NULL) { AfxMessageBox(TEXT("Failed to load library.")); return; } AddFunc addFunc = (AddFunc)GetProcAddress(hinstLib, "add"); if (addFunc == NULL) { AfxMessageBox(TEXT("Failed to get function address.")); FreeLibrary(hinstLib); return; } int result = addFunc(1, 2); CString str; str.Format(TEXT("1 + 2 = %d"), result); AfxMessageBox(str); FreeLibrary(hinstLib); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值