使用ctypes从Python调用C++: g++未定义引用
我有一台相机(thorlabs dcc1645c),它附带了“uc480.h”和“uc480.lib”这两个文件,可以用C++来编程。不过我现在想用Python来操作这台相机,所以我尝试按照Florian的建议,用Python调用一个C++类。
这是我的C++代码(Cam2.cpp):
\#include "uc480.h"
class Cam{
public:
UC480_CAMERA_LIST* pucl;
int nNumberOfCameras;
int GetNumberOfCameras(){
return is_GetNumberOfCameras(&nNumberOfCameras);
}
};
extern "C" {
Cam* Cam_new(){ return new Cam(); }
int Cam_GetNumberOfCameras(Cam* cam){ cam->GetNumberOfCameras(); }
}
我尝试用g++来编译:
g++ -fPIC -c Cam2.cpp -o Cam2.o
g++ -shared -Wl,-soname,libCam2.so -o libCam2.so Cam2.o
但是第二行出现了错误:
Cam2.o:Cam2.cpp:(.text$_ZN3Cam18GetNumberOfCamerasEv[Cam::GetNumberOfCameras()]+
0x1a): undefined reference to `__imp_is_GetNumberOfCameras'
collect2.exe: error: ld returned 1 exit status
‘is_GetNumberOfCameras’这个函数是在“uc480.lib”里定义的,所以我觉得可能是链接方面出了问题。我该怎么解决这个问题呢?
另外,请告诉我有没有其他方法可以用Python来使用这台相机。
2 个回答
感谢你们到目前为止的帮助。我找到了我的问题的解决办法。首先,这是我现在的C++代码:
#include "uc480.h"
class Cam{
public:
UC480_CAMERA_LIST* pucl = 0;
int nNumberOfCameras;
int GetNumberOfCameras(){
return is_GetNumberOfCameras(&nNumberOfCameras);
}
extern "C"{
__declspec(dllexport) Cam* Cam_New() { return new Cam(); }
__declspec(dllexport) int Cam_GetNumberOfCameras(Cam* obj){ return obj->GetNumberOfCameras(); }
}
我使用Visual Studio来创建一个DLL(动态链接库)。我按照这个说明的前几步进行了操作,链接在这里:http://msdn.microsoft.com/de-de/library/ms235636.aspx:
创建一个动态链接库(DLL)项目的步骤如下:
在菜单栏上,选择文件(File),然后选择新建(New),接着选择项目(Project)。
在新建项目对话框的左侧,展开已安装(Installed)、模板(Templates)、Visual C++,然后选择Win32。
在中间的区域,选择Win32控制台应用程序(Win32 Console Application)。
在解决方案名称框中输入一个名称,比如MyDLL,然后点击确定(OK)按钮。
在Win32应用程序向导对话框的概述页面上,点击下一步(Next)按钮。
在应用程序设置页面,找到应用程序类型(Application type),选择DLL。
点击完成(Finish)按钮来创建项目。
之后,我把我的C++代码添加到MyDLL.cpp中,并编译生成了MyDLL.dll。这个DLL可以用Python的ctypes来使用:
from ctypes import cdll
lib = cdll.LoadLibrary("PathToLib\MyDLL.dll")
class Camera(object):
def __init__(self):
self.obj = lib.Cam_New()
def GetNumberOfCameras(self):
return lib.Cam_GetNumberOfCameras(self.obj)
MyCam = Camera()
Numbers = MyCam.GetNumberOfCameras()
这对我来说运行得很好。
我记得得不太清楚,可能只需要在链接命令中加上库文件就行,比如这样:
g++ -shared -Wl,-soname,libCam2.so -o libCam2.so uc480.lib Cam2.o
或者,你可能需要在链接命令中加一个选项,比如 -L. -luc480
,前提是这个库文件和代码在同一个文件夹里。