Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use boost.python to call C++ dynamic Library in linux

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)05/31 Report--

Today, the editor will share with you how to use boost.python to call C++ dynamic library in linux. The content is detailed and the logic is clear. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article.

Understand the essence of extern "C"

Before we talk about the first method, let's briefly introduce the function of the extern "c" method. Specific explanation can refer to this blog, very detailed, recommended to read. For example, in C, there is a function.

Intad (inta,intb); if you use the gcc compiler, the name generated by the compilation is add, but if you use the g compiler, the name generated by the compilation may be similar to that of ABaddCD, including the function name, number of parameters, type, and return value. So, if an overload

Float DD (float,float b); maybe the compiled name is a bit like EFaddGH, which also contains information about function names, input parameters, return values, and so on, so c can be overloaded. Just imagine, if you use the gcc compiler, it's called add, so you can't tell which function, so you can't overload it. Then the function of extern "c" is to tell the g compiler to compile int add (int aint b) into add instead of ABaddCD, because add can be recognized by c language, ABaddCD can not be recognized by c language, and c language will think that add is an "undefined symbol". Therefore, we can also see here that extern "c" can only be used for c code. In addition, for overloaded c functions, you need to write and call two different functions to ensure that the names are not duplicated.

Python uses extern "C" mode to call C++ dynamic library

After we know the nature of extern "c", we encapsulate it in this way. I directly take the source code of the C dynamic library, encapsulate a layer of C interface on the source code, and then generate the dynamic library. Suppose the dynamic library encapsulated as addc,c by add function is called a, and the dynamic library generated by encapsulating a layer of c interface is called B. if you write a test code of test.c, check the dynamic library b with pure c code, and call the addc function, the result is feasible and successful. But check the dynamic library B with python, call the addc function, and find that the error will be reported:

Attribute error: B.so: undefined symbol: add

That is, the add function is still not recognized. Use

You can get NmB.so | grepadd

Automatic control of data flow

ABaddCD

In this way, the first addc must be recognized by python, and the second ABaddCD, the name generated by G compilation, cannot be called by python. I'm just giving my own example. My own C dynamic library source code may be complex and the python call is not successful. There are many examples that can be successfully invoked on the Internet. So the reader can experiment by himself, and if it can be successfully invoked, it is naturally the best. Because the way I'm going to use boost.python next is tortuous.

Python uses boost.python to call C++ dynamic library

Solve other third-party libraries that C++ dynamic libraries depend on

Because my dynamic libraries depend on other third-party library files, such as openssl, uuid, libevent, and pthread, python needs to load these dynamic libraries no matter which method I use to call the C dynamic library. The specific python code is as follows:

Fromctypesimport *

Ctypes . CDLL ('libssl.so', mode=ctypes. RTLD_GLOBAL)

Ctypes . CDLL ('libcrypto.so', mode=ctypes. RTLD_GLOBAL)

Ctypes . CDLL ('libuuid.so', mode=ctypes. RTLD_GLOBAL)

Ctypes . CDLL ('/ usr/lib64/libevent.so', mode=ctypes. RTLD_GLOBAL)

# ctypes . CDLL ('/ usr/lib64/li)

Bpthread.so.0 ", mode=ctypes.RTLD_GLOBAL)

Some can be loaded by default, such as libpthread.so, which we do not need to load, while others need to be loaded manually, such as libssl.so,libuuid.so, which are all in the / usr/lib64/ directory without adding a path, but the libevent library is also in the / usr/lib64 directory, and there is also a path in the / usr/lib/ directory, and you must add a path. So, if the compilation fails, use whereis libevent.so to see which directory it is in, and then add the absolute path. Sometimes the absolute path is still wrong, such as libpthread.so, and the error is still reported after adding the absolute path.

'OSError: / usr/lib64/libpthread.so: invalid ELF header'

This means that the version number is wrong. If you find the version number of the libpthread.so link and add the. 0 version number, there will be no error.

C++ code configuration boost environment

On the centos6.6 machine where the C++ dynamic library is located, I refer to: the dynamic link library configuration and test boost of the ubuntu python calling the Cmax Candle + method. Reference: use Boost.Python to achieve Python Cramp Candle + mixed programming to achieve python definition of C++ function overload. When configuring the environment, the command I use is: yum install boost*, yum install python-devel, refer to these two articles to achieve boost, basically can pass, encountered problems, there are also. In addition, I also encountered other problems. I found a solution on Stack Overflow. I will directly post the results below:

Create a new test.cpp, in which we will define the functions available to python.

In the test.cpp code, include the following code:

/ / need to include boost header file # include#include#include// overloaded function implementation, in my C++ code, LOGIN function, Synchronize_Request function, Notify function all have three overloaded functions, below I only use one of the LOGIN function, a Synchronize_Request function, two Notify functions, such as the following fun3 and fun4, is two different notify. / / only functions that are overloaded need to define fun1,fun2,fun3,fun4 like this. There is no overloaded function. You can write the name int (* fun1) (constintserver_type,constintrequest_no,std::string&login_result) = & LOGIN;int (* fun2) (constintserver_type,constintrequest_no,std::string&recv_answer) = & Synchronize_Request;int (* fun3) (constintserver_type,unsignedinttimeout_ms,unsignedintsesscare) = & Notify;int (* fun4) (void) = & Notify directly. / / add function overload example int (* fun5) (inta,intb) = & add;BOOST_PYTHON_MODULE (libB) / / python module. The name of libB should be the same as that of .so. {usingnamespaceboost::python;//Initialize function is not overloaded and can be used directly. There is no need to define fun1def ("Initialize", Initialize) as above; / / Uninitialize function is not overloaded and can be used directly ("Uninitialize", Uninitialize); def ("LOGIN", fun1) Def ("Synchronize_Request", fun2); def ("Notify", fun3); def ("Notify2", fun4); def ("add", fun5); / / python can call the functions defined by def above}

The commands used by Makefile are:

% .o:% .cppg + +-g-lssl-fPIC-levent-lcrypto-luuid-lpthread-lrt-lboost\ _ filesystem-lboost\ _ system-lboost_python-lpython-I/usr/include/python2.7-o$@-c$

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report