2

我有一个 C DLL,它公开了一些返回void pointers类的方法,如下所示:

void *GetLicense() {
    static AppLicenseImpl ipds_;
    return (void *) &ipds_;
}

在 C++ 中,加载 DLL 后,我会这样做:

typedef void *(* FPGetLicense)();
GetLicense_ = (FPGetLicense)GetAddress("GetLicense");
license_ = (AppLicense *) GetLicense_();
license_->GetApplicationStatus(); // Load data so that other calls don't fail

我不知道如何在 Python 中进行并行处理。这让我得到了指针:

d = ctypes.cdll.LoadLibrary('license.dll')
d.GetLicense.restype = ctypes.c_void_p
p = d.GetLicense() # returns ptr loc, something like 8791433660848L

但我显然不能p.GetApplicationStatus()用 Python 调用。有没有人建议我如何在 Python 中以其他方式实例化该类以便我可以调用GetApplicationStatus()

4

2 回答 2

3

引用文档

有时您有不兼容类型的实例。在 C 中,您可以将一种类型转换为另一种类型。ctypes提供了cast()可以以相同方式使用的功能。

因此,C++ 代码的 Python 等价物是:

license = cast(d.GetLicense(), ctypes.POINTER(AppLicense))
license.GetApplicationStatus()

但是,这通常不是必需的。你也许可以这样做:

d.GetLicense.restype = ctypes.POINTER(AppLicense)

这看起来像“作弊”,但事实并非如此。你只是告诉它POINTER(AppLicense)用结果调用构造函数。并且由于POINTER(AppLicense)是 ctypes 数据类型,因此不必首先假设结果是 C int

于 2013-10-15T19:14:09.143 回答
1

我花了更多时间在这上面——从 c++ 开始,当我想使用 void 指针所指的类实例时,我做了这样的事情:

class AppLicense {
public:
    AppLicense() {}
    virtual LicenseStatus GetApplicationStatus() = 0;
}

但我不知道如何在 Python 中做到这一点。这不起作用:

class AppLicense(object):
  def GetApplicationStatus(self):
    pass

因此,我在 dll 中导出了另一个函数,如下所示:

extern "C" {
    int P_GetApplicationStatus(void *ptr) {
        try {
            AppLicenseImpl * ref = reinterpret_cast<AppLicenseImpl *>(ptr);
            return ref->GetApplicationStatus();
        } catch (...) {
            return 0; // License Error default.
        }
    }
}

一旦我有了它,从 Python 中使用它是这样完成的:

d.GetLicense.restype = ctypes.c_void_p
p = d.GetLicense()

d.C_GetApplicationStatus.argtypes = [ctypes.c_void_p]
status = d.P_GetApplicationStatus(p)
于 2013-10-17T15:52:24.493 回答