Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Ctypes从Void指针创建C类实例_Python_C_Ctypes_Void Pointers - Fatal编程技术网

Python 使用Ctypes从Void指针创建C类实例

Python 使用Ctypes从Void指针创建C类实例,python,c,ctypes,void-pointers,Python,C,Ctypes,Void Pointers,我有一个C DLL,它公开了一些方法,这些方法将void指针返回给这样的类: void *GetLicense() { static AppLicenseImpl ipds_; return (void *) &ipds_; } 在C++中,加载DLL后,我会这样做: typedef void *(* FPGetLicense)(); GetLicense_ = (FPGetLicense)GetAddress("GetLicense"); license_ = (Ap

我有一个C DLL,它公开了一些方法,这些方法将
void指针
返回给这样的类:

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
但是我显然不能在Python中调用
p.GetApplicationStatus()
。有人建议我如何在Python中实例化该类,以便调用
GetApplicationStatus()

引用:

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

这样,C++代码的Python等价是:

license = cast(d.GetLicense(), ctypes.POINTER(AppLicense))
license.GetApplicationStatus()
然而,这通常是不必要的;您可以这样做:

d.GetLicense.restype = ctypes.POINTER(AppLicense)
这看起来像是“作弊”,但事实并非如此。您只是告诉它调用带有结果的
指针(AppLicense)
构造函数。由于
指针(AppLicense)
是一种ctypes数据类型,它不必首先假定结果是一个C
int

引用:

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

这样,C++代码的Python等价是:

license = cast(d.GetLicense(), ctypes.POINTER(AppLicense))
license.GetApplicationStatus()
然而,这通常是不必要的;您可以这样做:

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

这看起来像是“作弊”,但事实并非如此。您只是告诉它调用带有结果的
指针(AppLicense)
构造函数。由于指针(Apple)>代码>是一个cType数据类型,它不必首先假定结果是C<代码> int <代码> .< /P> < P>我花了更多时间来处理这个——从C++中,当我想使用类实例时,空指针指的是我这样做:

class AppLicense {
public:
    AppLicense() {}
    virtual LicenseStatus GetApplicationStatus() = 0;
}
extern "C" {
    int P_GetApplicationStatus(void *ptr) {
        try {
            AppLicenseImpl * ref = reinterpret_cast<AppLicenseImpl *>(ptr);
            return ref->GetApplicationStatus();
        } catch (...) {
            return 0; // License Error default.
        }
    }
}
d.GetLicense.restype = ctypes.c_void_p
p = d.GetLicense()

d.C_GetApplicationStatus.argtypes = [ctypes.c_void_p]
status = d.P_GetApplicationStatus(p)
但我不知道如何在Python中实现这一点。这不起作用:

class AppLicense(object):
  def GetApplicationStatus(self):
    pass
因此,我在dll中导出了另一个函数,如下所示:

class AppLicense {
public:
    AppLicense() {}
    virtual LicenseStatus GetApplicationStatus() = 0;
}
extern "C" {
    int P_GetApplicationStatus(void *ptr) {
        try {
            AppLicenseImpl * ref = reinterpret_cast<AppLicenseImpl *>(ptr);
            return ref->GetApplicationStatus();
        } catch (...) {
            return 0; // License Error default.
        }
    }
}
d.GetLicense.restype = ctypes.c_void_p
p = d.GetLicense()

d.C_GetApplicationStatus.argtypes = [ctypes.c_void_p]
status = d.P_GetApplicationStatus(p)

我在C++中花费了更多的时间,当我想用空指针引用的类实例时,我做了这样的事情:

class AppLicense {
public:
    AppLicense() {}
    virtual LicenseStatus GetApplicationStatus() = 0;
}
extern "C" {
    int P_GetApplicationStatus(void *ptr) {
        try {
            AppLicenseImpl * ref = reinterpret_cast<AppLicenseImpl *>(ptr);
            return ref->GetApplicationStatus();
        } catch (...) {
            return 0; // License Error default.
        }
    }
}
d.GetLicense.restype = ctypes.c_void_p
p = d.GetLicense()

d.C_GetApplicationStatus.argtypes = [ctypes.c_void_p]
status = d.P_GetApplicationStatus(p)
但我不知道如何在Python中实现这一点。这不起作用:

class AppLicense(object):
  def GetApplicationStatus(self):
    pass
因此,我在dll中导出了另一个函数,如下所示:

class AppLicense {
public:
    AppLicense() {}
    virtual LicenseStatus GetApplicationStatus() = 0;
}
extern "C" {
    int P_GetApplicationStatus(void *ptr) {
        try {
            AppLicenseImpl * ref = reinterpret_cast<AppLicenseImpl *>(ptr);
            return ref->GetApplicationStatus();
        } catch (...) {
            return 0; // License Error default.
        }
    }
}
d.GetLicense.restype = ctypes.c_void_p
p = d.GetLicense()

d.C_GetApplicationStatus.argtypes = [ctypes.c_void_p]
status = d.P_GetApplicationStatus(p)

你所说的“在剩下的过程中实例化那个类”是什么意思?当代码< > GuestRux至少返回它最好是,或者C++的下一行会出错时,这个实例已经被完全实例化了。我的道歉,我的术语可能是坏的。这是否需要在我的Python模块中有一个类似的类定义来反映c/c++代码中的
AppLicense
类?好吧,您的c代码不可能有任何对
AppLicense
类的引用。除此之外,没有一种真正的可移植方式来引用来自.dll/.C++的C++类型。这就是为什么通常有
extern“C”
wrappers,它们首先将struct或void*作为第一个参数。但是,如果要从
ctypes
访问结构或类的成员,则需要定义
ctypes.struct
。如果您不想这样做,请考虑使用<代码> CFFI <代码>或建立自定义绑定(可能使用<代码> Cython < /代码>),而不是使用<代码> cType 。然后实例<代码>“自我/代码>”是指向C++对象的指针。增加调用C++方法的<<代码>外部“C”<代码>存根的方法。添加一个
\u check\u retval\u
方法,以在类用作
restype
时集中错误检查该类。导出一个
extern“C”
函数,例如
AppLicense\u GetApplicationStatus
,该函数采用
AppLicense*
并调用
GetApplicationStatus
方法。Python
AppLicense
类(c\u void\u p的子类)有一个
GetApplicationStatus
方法,该方法调用
d.AppLicense\u GetApplicationStatus(self)
。您可以设置代码> d.GigLiNeSE.ReSype=Apple Stices < /Calp>等。正如Abnnt所提到的,您可能想研究包装C++库(如Booj.python或Sigg)的替代方案。“将其余的类实例化为”是什么意思?当代码< > GuestRux至少返回它最好是,或者C++的下一行会出错时,这个实例已经被完全实例化了。我的道歉,我的术语可能是坏的。这是否需要在我的Python模块中有一个类似的类定义来反映c/c++代码中的
AppLicense
类?好吧,您的c代码不可能有任何对
AppLicense
类的引用。除此之外,没有一种真正的可移植方式来引用来自.dll/.C++的C++类型。这就是为什么通常有
extern“C”
wrappers,它们首先将struct或void*作为第一个参数。但是,如果要从
ctypes
访问结构或类的成员,则需要定义
ctypes.struct
。如果您不想这样做,请考虑使用<代码> CFFI <代码>或建立自定义绑定(可能使用<代码> Cython < /代码>),而不是使用<代码> cType 。然后实例<代码>“自我/代码>”是指向C++对象的指针。增加调用C++方法的<<代码>外部“C”<代码>存根的方法。添加一个
\u check\u retval\u
方法,以在类用作
restype
时集中错误检查该类。导出一个
extern“C”
函数,例如
AppLicense\u GetApplicationStatus
,该函数采用
AppLicense*
并调用
GetApplicationStatus
方法。Python
AppLicense
类(一个子类