动态链接和Python SWIG(C ++)在C ++中的工作在python中失败 [英] Dynamic linking and Python SWIG (C++) works in C++ fails in python

查看:107
本文介绍了动态链接和Python SWIG(C ++)在C ++中的工作在python中失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个库,我已经使用SWIG创建了一个python包装。库本身接受在动态链接的.so文件中的用户提供的函数。目前,我处理一个我创造了自己,并设法得到动态链接工作...在C + +。当我试图运行它在python我得到未定义的符号错误。这些符号是不存在于提供的.so文件中但是存在于主程序中的符号(实质上它们是允许所提供的模块从主程序访问数据的函数)。



我没有得到任何错误运行一个简短的测试程序在C + +,但一个简短的测试程序在python与这个包装器(以前工作)失败。我不能想到一个解释为什么它会失败在C + +而不是在Python。我担心我有点担心的是C ++不能正常工作,但不告诉我,而Python正在拾取C ++不是错误。然而,C ++返回的结果是准确的,所以这似乎不太可能。



任何想法这是怎么可能的,因此如何解决它?



感谢。



更新:
我已将此代码添加到程序顶部:

  import dl 
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)

这样可以摆脱运行时错误,但不幸的是会出现第二个问题(仍然是由于链接)。从作为主程序的一部分的动态链接库中调用的函数不返回正确的值。他们正在返回0.更显而易见的是,他们甚至根本没有运行。问题变成了实际运行的是什么,为什么它不同于C ++,如何修复THAT?



再次感谢。



更新 - 一个更清晰的解释
Python导入一个模块,这是我的C ++库已被SWIG包装。这个C ++库使用dlopen和dlsym从用户提供的.so文件获取函数。用户提供对作为C ++库一部分的函数的文件调用,以便完成它的工作。从.so文件到C ++库的函数调用是失败的部分,即它们无法调用该函数,只返回0.然而,这种失败只发生在测试代码是用python编写的。使用库的C ++测试代码运行良好。

解决方案

解决方案是确保python预加载C ++主库全局范围。
这不是一个非常优雅的解决方案,我不想这样做,但它使它工作的时刻。



围绕此处,并识别每次启动时必须设置的LD_LIBRARY_PATH环境变量终端为了它甚至找到已经SWIGed的主要C ++库,我注意到LD_PRELOAD环境变量。将此设置为主C ++库的文件名,程序工作。



我怀疑这是因为它可以用于选择性地覆盖其他共享库中的函数。



如果任何人提出比设置环境变量更好的答案,它将是真棒,因为我不知道这是多么便携。



编辑:最初的问题是,用户提供的库正在查找的函数不在全局范围内。为了解决这个问题,只需使用python的dl.open打开主库的.so文件,使用dl.RTLD_NOW和dl.RTLD_GLOBAL。



成功! p>

I have a library for which I have created a python wrapper using SWIG. The library itself accepts user provided functions which are in an .so file that is dynamically linked. At the moment I'm dealing with one that I have created myself and have managed to get the dynamic linking working... in C++. When I attempt to run it in python I get undefined symbol errors. These symbols are ones that are not present in the provided .so file but are present in the main program (essentially they are the functions that allow the provided module to access data from the main program).

I do not get any errors running a short test program in C++, but a short test program in python with this wrapper (that worked previously) fails. I can't think of an explanation as to why it would fail in C++ and not in the python. What worries me slightly is the idea that the C++ isn't working properly but isn't telling me, and the python is picking up errors that the C++ isn't. Yet the result returned by the C++ is accurate, so this seems unlikely.

Any thoughts how this is possible and hence how I could fix it?

Thanks.

Update: I have added this code to the top of the program:

import dl
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)

This gets rid of the runtime error, but unfortunately allows a second problem to arise (still due to linking). The functions that are being called from within the dynamically linked library that are part of the main program are not returning the correct values. They are returning 0. What's more it's evident that they are not even being run at all. The question becomes what is actually being run, why is it different to the C++, and how do I fix THAT?

Thanks again.

Update- A potentially clearer explanation Python imports a module, which is my C++ library that has been wrapped by SWIG. This C++ library uses dlopen and dlsym to obtain functions from a user provided .so file. The user provided file calls to functions that are part of the C++ library in order to do it's job. The function calls from the .so file to the C++ library are the part that is failing, that is they fail to call the function and simply return 0. However this failure only occurs when the test code is written in python. C++ test code that uses the library works fine.

解决方案

A solution is to make sure that python is preloading the C++ main library in the global scope. This is not a very elegant solution, and I don't want to do it, but it makes it work for the moment.

After a little poking around here and recognising the LD_LIBRARY_PATH environment variable that I have to set every time I start the terminal in order for it to even find the main C++ library that has been SWIGed, I noticed the LD_PRELOAD environment variable. Upon setting this to the filename of the main C++ library the program worked.

I suspect this is because it "can be used to selectively override functions in other shared libraries".

If anyone comes up with a better answer than setting environment variables it'd be awesome, as I'm not sure how portable this is.

Edit: The original problem is that the functions that the user provided library is looking for are not in the global scope. In order to fix this simply using python's "dl.open" to open the main library's .so file, using dl.RTLD_NOW and dl.RTLD_GLOBAL.

Success!

这篇关于动态链接和Python SWIG(C ++)在C ++中的工作在python中失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆