Ctypes“符号未找到”用于OSX中的动态库 [英] Ctypes "symbol not found" for dynamic library in OSX

查看:561
本文介绍了Ctypes“符号未找到”用于OSX中的动态库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了一个C ++库,并从它建立了一个.dylib动态库。但是,当我用ctypes加载它时,它会失败。有些东西似乎没有正确链接。我不知道为什么。错误(相关部分):

pre code $ cscalelib.setup_framebuffer(flip,surface.frame_buffer,surface.texture,surface._scale [ 0],surface._scale [1])$ ​​b $ b文件/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/ctypes/__init__.py,第325行,位于__getattr__
func = self .__ getitem __(name)
文件/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/ctypes/__init__.py,第330行,位于__getitem__
func = self._FuncPtr((name_or_ordinal,self))
AttributeError:dlsym(0x56ecd0,setup_framebuffer):找不到符号

以下是仍在进行中的C ++代码,但应该与我目前使用的代码一致。

  #include< OpenGL / gl.h> 
#include< OpenGL / glu.h>
#include< vector.h>

void setup_framebuffer(bool flip,GLuint frame_buffer_id,gluint texture_id,int width,int height){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,frame_buffer_id);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,texture_id,0);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //加载投影矩阵
if(flip){
gluOrtho2D(0,width,height,0);
} else {
gluOrtho2D(0,width,0,height);
}
}
void end_framebuffer(){
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //加载投影矩阵
gluOrtho2D(0,1280,720,0); //设置一个正交视图
}
void add_lines(bool antialias,vector< vector< double>> coordinate,double w,double r,double g,double b,double a){
glDisable(GL_TEXTURE_2D);
if(antialias){
glEnable(GL_LINE_SMOOTH); //启用线条平滑。
}
glColor4d(r,g,b,a);
glLineWidth(w);
glBegin(GL_LINE_STRIP);
for(int x = 0; x< coordinates.size(); x ++){
glVertex2d(coordinates [x] [0],coordinates [x] [1]);
}
glEnd();
if(antialias){
glDisable(GL_LINE_SMOOTH); //禁用线条平滑。
}
glEnable(GL_TEXTURE_2D);
}

我将它编译为:

g ++ -dynamiclib CPPEXTSCALELIB.cp -framework opengl -arch i386 -o CPPEXTSCALELIB.dylib



以下是用...表示不相关部分的Python代码。

  ... 
from ctypes import *
...
cscalelib = CDLL (os.path.dirname(sys.argv [0])+/CPPEXTSCALELIB.dylib)
...
def setup_framebuffer(surface,flip = False):
#Create texture如果尚未完成,
如果surface.texture为None:
create_texture(surface)
#Render子级父级
如果surface.frame_buffer为None:
surface.frame_buffer = glGenFramebuffersEXT(1)
cscalelib.setup_framebuffer(flip,surface.frame_buffer,surface.texture,surface._scale [0],surface._scale [1])$ ​​b $ b ...
<

解决方案

>这个问题很可能是因为你正在使用C ++,因此也是e函数名称将被改变并使用C ++调用约定。如果使用 externC声明函数,那么它应该以可从C代码(以及来自Python的CTypes模块)调用的方式导出。


I have made a C++ library and have built a .dylib dynamic library from it. However when I load it with ctypes, it fails. Something doesn't seem to have linked properly. I have no idea why. The error (The relevant part):

    cscalelib.setup_framebuffer(flip,surface.frame_buffer,surface.texture,surface._scale[0],surface._scale[1])
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/ctypes/__init__.py", line 325, in __getattr__
    func = self.__getitem__(name)
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/ctypes/__init__.py", line 330, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(0x56ecd0, setup_framebuffer): symbol not found

Here's the C++ code which is still in progress but should work with what I have so far.

#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <vector.h>

void setup_framebuffer(bool flip,GLuint frame_buffer_id,GLuint texture_id,int width,int height){
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer_id);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture_id, 0);
    glPushAttrib(GL_VIEWPORT_BIT);
    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); //Load the projection matrix
    if (flip){
        gluOrtho2D(0,width,height,0);
    }else{
        gluOrtho2D(0,width,0,height);
    }
}
void end_framebuffer(){
    glPopAttrib();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); //Load the projection matrix
    gluOrtho2D(0,1280,720,0); //Set an orthorgraphic view
}
void add_lines(bool antialias,vector< vector<double> > coordinates,double w,double r,double g, double b,double a){
    glDisable(GL_TEXTURE_2D);
    if (antialias){
        glEnable(GL_LINE_SMOOTH); //Enable line smoothing.
    }
    glColor4d(r,g,b,a);
    glLineWidth(w);
    glBegin(GL_LINE_STRIP);
    for (int x = 0; x < coordinates.size(); x++) {
        glVertex2d(coordinates[x][0],coordinates[x][1]);
    }
    glEnd();
    if (antialias){
        glDisable(GL_LINE_SMOOTH); //Disable line smoothing.
    }
    glEnable(GL_TEXTURE_2D);
}

I compiled it with:

g++ -dynamiclib CPPEXTSCALELIB.cp -framework opengl -arch i386 -o CPPEXTSCALELIB.dylib

Here's the Python code with "..." to represent irrelevant parts.

...
from ctypes import *
...
cscalelib = CDLL(os.path.dirname(sys.argv[0]) + "/CPPEXTSCALELIB.dylib")
...
def setup_framebuffer(surface,flip=False):
    #Create texture if not done already
    if surface.texture is None:
        create_texture(surface)
    #Render child to parent
    if surface.frame_buffer is None:
        surface.frame_buffer = glGenFramebuffersEXT(1)
    cscalelib.setup_framebuffer(flip,surface.frame_buffer,surface.texture,surface._scale[0],surface._scale[1])
...

Thank you.

解决方案

The problem is most likely the fact that you are using C++, and hence the function name will be mangled and use C++ calling conventions. If you declare the function with extern "C" then it should be exported in such a way as to callable from C code (and from Python's CTypes module).

这篇关于Ctypes“符号未找到”用于OSX中的动态库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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