linux从动态链接库导出 c++ class

1、源文件

无需如windows那样在类的头文件添加dllexport, dllimport

2library 编译选项务必添加 -fPIC flag

如果是cmake,则:

add_library(${PROJECT_NAME} SHARED

  ${${PROJECT_NAME}_SRC}

)

set_property(TARGET ${PROJECT_NAME} PROPERTY  POSITION_INDEPENDENT_CODE ON) #相当于指定-fPIC编译选项

 

3、在调用的客户工程中设置:

target_link_libraries(${PROJECT_NAME} ${VTK_LIBRARIES} ${RL_LIBRARIES} rbs_urdf)

# 这里rbs_urdf是lib工程名

4、相关教程

Creating and using shared libraries with different compilers on different operating systems - Gernot.Klingler (gernotklingler.com)

CMake: 设置编译选项_cmake 添加编译选项-CSDN博客

[CMake] How to add -fPIC to a static library?

c++ - Runtime "symbol lookup error" after compilation and linking of .so - Stack Overflow

文中是linuxC++动态库 实现接口提供导出的一个例子 注意其中使用函数返回基指针的用法,因为Linux动态链接库不能像MFC中那样直接导出 一、介绍 如何使用dlopen API动态地加载C++函数和,是Unix C++程序员经常碰到的问题。 事实上,情况偶尔有些复杂,需要一些解释。这正是写这篇mini HOWTO的缘由。 理解这篇文档的前提是对C/C++语言中dlopen API有基本的了解。 这篇HOWTO的维护链接是: http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/ 二、问题所在 有时你想在运行时加载一个库(并使用其中的函数),这在你为你的程序写一些插件或模块架构的时候经常发生。 在C语言中,加载一个库轻而易举(调用dlopen、dlsym和dlclose就够了),但对C++来说,情况稍微复杂。 动态加载一个C++库的困难一部分是因为C++的name mangling (译者注:也有人把它翻译为“名字毁坏”,我觉得还是不翻译好), 另一部分是因为dlopen API是用C语言实现的,因而没有提供一个合适的方式来装载。 在解释如何装载C++库之前,最好再详细了解一下name mangling。 我推荐您了解一下它,即使您对它不感兴趣。因为这有助于您理解问题是如何产生的,如何才能解决它们。 1. Name Mangling 在每个C++程序(或库、目标文件)中, 所有非静态(non-static)函数在二进制文件中都是以“符号(symbol)”形式出现的。 这些符号都是唯一的字符串,从而把各个函数在程序、库、目标文件中区分开来。 在C中,符号名正是函数名:strcpy函数的符号名就是“strcpy”,等等。 这可能是因为两个非静态函数的名字一定各不相同的缘故。 而C++允许重载(不同的函数有相同的名字但不同的参数), 并且有很多C所没有的特性──比如、成员函数、异常说明──几乎不可能直接用函数名作符号名。 为了解决这个问题,C++采用了所谓的name mangling。它把函数名和一些信息(如参数数量和大小)杂糅在一起, 改造成奇形怪状,只有编译器才懂的符号名。 例如,被mangle后的foo可能看起来像foo@4%6^,或者,符号名里头甚至不包括“foo”。 其中一个问题是,C++标准(目前是[ISO14882])并没有定义名字必须如何被mangle, 所以每个编译器都按自己的方式来进行name mangling。 有些编译器甚至在不同版本间更换mangling算法(尤其是g++ 2.x和3.x)。 即使您搞清楚了您的编译器到底怎么进行mangling的,从而可以用dlsym调用函数了, 但可能仅仅限于您手头的这个编译器而已,而无法在下一版编译器下工作。 三、 使用dlopen API的另一个问题是,它只支持加载函数。 但在C++中,您可能要用到库中的一个,而这需要创建该的一个实例,这不容易做到。 四、解决方案 1. extern "C" C++有个特定的关键字用来声明采用C binding的函数: extern "C" 。 用 extern "C"声明的函数将使用函数名作符号名,就像C函数一样。 因此,只有非成员函数才能被声明为extern "C",并且不能被重载。 尽管限制多多,extern "C"函数还是非常有用,因为它们可以象C函数一样被dlopen动态加载。 冠以extern "C"限定符后,并不意味着函数中无法使用C++代码了, 相反,它仍然是一个完全的C++函数,可以使用任何C++特性和各种型的参数。
### 回答1: Python可以通过使用C或C++编写的扩展模块来封装成动态链接库(DLL)。这可以通过使用Python的C API和相应的编译器工具实现。 首先,我们需要使用C或C++编写一个扩展模块。这个扩展模块包含在Python中定义的函数,以及与Python解释器交互的代码。在扩展模块中,可以使用Python提供的C API来调用Python解释器,执行Python代码或访问Python对象。 接下来,我们需要将这个扩展模块编译成动态链接库。在Windows上,可以使用Microsoft Visual C++或MinGW等工具,将C或C++代码编译成DLL。在Linux上,可以使用GCC等编译器。 完成编译后,我们可以在Python中使用ctypes模块来加载和调用这个动态链接库。ctypes模块提供了一种使用动态链接库的简单方法,它可以自动处理函数导出和数据型转换。 通过加载这个动态链接库,我们可以在Python中直接调用其中定义的函数,而无需了解其底层的C或C++实现细节。这种方式使得我们可以在Python中使用高性能、底层的C或C++代码,同时保持Python的简洁和易用性。 总结而言,Python可以通过编写扩展模块,并将其编译成动态链接库,实现封装。这种方法可以提供Python与底层C或C++代码的无缝集成,以及更高的性能和灵活性。 ### 回答2: Python可以使用ctypes模块将其封装为动态链接库(DLL),以便在其他编程语言中使用Python代码。以下是封装Python为动态链接库的步骤: 1. 导入ctypes模块:首先要导入ctypes模块,该模块允许Python与C库进行交互。 2. 加载Python解释器:使用ctypes模块的cdll.LoadLibrary函数加载Python解释器。此步骤将Python解释器加载到内存中。 3. 封装Python函数:使用ctypes模块的CFUNCTYPE函数定义Python函数的签名。然后可以使用ctypes模块的函数指针将Python函数转换为C函数。 4. 导出C函数:将C函数导出动态链接库的接口,以便其他编程语言可以调用。 5. 调用动态链接库:在其他编程语言中,可以使用相应的库加载机制来加载和调用Python函数。 通过以上步骤,可以将Python代码封装为动态链接库,以便在其他编程语言中使用。这种封装方式有助于在其他语言中重用Python代码,并提供了跨语言开发的便利性。 ### 回答3: Python可以将模块封装成动态链接库,使其可以被其他编程语言调用。Python提供了一种称为ctypes的标准库,可用于将Python模块封装成动态链接库。 使用ctypes,可以将Python模块转化为可在其他编程语言中使用的动态链接库。要封装Python模块为动态链接库,需要遵循以下步骤: 1. 导入ctypes模块 2. 找到要封装的Python模块 3. 定义所需的函数和数据结构 4. 将函数和数据结构包装在一个中 5. 使用ctypes将该转化为动态链接库 下面是一个简单的示例,将一个Python函数封装成动态链接库: ```python import ctypes # 导入Python模块 import math # 定义包装 class MathFunctions: # 封装函数 @staticmethod def calculate_sine(x): return math.sin(x) # 将转化为动态链接库 lib = ctypes.CDLL('./libmath.so') lib.calculate_sine.restype = ctypes.c_double lib.calculate_sine.argtypes = [ctypes.c_double] # 使用动态链接库中的函数 result = lib.calculate_sine(1.0) print(result) ``` 在上面的示例中,`lib = ctypes.CDLL('./libmath.so')`将`MathFunctions`转化为动态链接库。然后,可以使用动态链接库中的函数`calculate_sine`来计算正弦值。 通过这种方式,Python模块可以被其他编程语言调用,从而扩展了Python的应用范围。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值