使用ctypes从Python调用C++: g++未定义引用

0 投票
2 回答
1010 浏览
提问于 2025-04-18 03:42

我有一台相机(thorlabs dcc1645c),它附带了“uc480.h”和“uc480.lib”这两个文件,可以用C++来编程。不过我现在想用Python来操作这台相机,所以我尝试按照Florian的建议,用Python调用一个C++类。

如何从Python调用C/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 个回答

-1

感谢你们到目前为止的帮助。我找到了我的问题的解决办法。首先,这是我现在的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)项目的步骤如下:

  1. 在菜单栏上,选择文件(File),然后选择新建(New),接着选择项目(Project)。

  2. 在新建项目对话框的左侧,展开已安装(Installed)、模板(Templates)、Visual C++,然后选择Win32。

  3. 在中间的区域,选择Win32控制台应用程序(Win32 Console Application)。

  4. 在解决方案名称框中输入一个名称,比如MyDLL,然后点击确定(OK)按钮。

  5. 在Win32应用程序向导对话框的概述页面上,点击下一步(Next)按钮。

  6. 在应用程序设置页面,找到应用程序类型(Application type),选择DLL。

  7. 点击完成(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()

这对我来说运行得很好。

0

我记得得不太清楚,可能只需要在链接命令中加上库文件就行,比如这样:

g++  -shared -Wl,-soname,libCam2.so -o libCam2.so uc480.lib Cam2.o

或者,你可能需要在链接命令中加一个选项,比如 -L. -luc480,前提是这个库文件和代码在同一个文件夹里。

撰写回答