为c/c++代码编写ctypes包装器的正确方法
Correct way of writing a ctypes wrapper for c/c++ code
感谢您花时间阅读,我希望您能回答:)
我将首先解释我所做的研究等等,试图纠正这个问题,只是为了提供一些背景。此外,我认为自己有相当强的python知识。
我查阅了DLL/neneneba API文档试图理解,我也花了一天时间复习c++,试图理解我的问题:
我有一个C++(我很确定)程序,我想在python中实现它。我觉得我知道如何尝试转换(ahem),除了一部分我无法理解(我知道这是一个开始,但我相信其他部分应该到位)
#import "pstorec.dll" no_namespace
void foo()
{
IPStorePtr PStore;
IEnumPStoreTypesPtr EnumPStoreTypes;
我一辈子都无法理解第5/6行发生了什么,也无法理解如何在python/c中实现这一点类型。
我试着把它们称为"pstorec.dll"的函数,但当然,这不起作用,有人能解释一下吗。我已经通读了http://starship.python.net/crew/theller/ctypes/tutorial.html我个人找不到解决办法。所以我很清楚我误解了什么。
谢谢,提前。
p.s,我知道第一个单词(variable?)想要成为一个指针,但除此之外,我迷失了方向。希望有人能理解我的要求:)
以下完整代码:
#import "pstorec.dll" no_namespace
void ListIEProtectedStorageSecrets()
{
IPStorePtr PStore;
IEnumPStoreTypesPtr EnumPStoreTypes;
GUID TypeGUID;
char strSiteUrl[1024];
char strSiteCredentials[1024];
char szItemGUID[1024];
char strUsername[1024];
char strPassword[1024];
HRESULT hRes = PStoreCreateInstance(&PStore, 0, 0, 0);
hRes = PStore->EnumTypes(0, 0, &EnumPStoreTypes);
while( EnumPStoreTypes->raw_Next(1, &TypeGUID, 0) == S_OK )
{
sprintf_s(szItemGUID, 1024, "%x", TypeGUID);
IEnumPStoreTypesPtr EnumSubTypes;
hRes = PStore->EnumSubtypes(0, &TypeGUID, 0, &EnumSubTypes);
GUID subTypeGUID;
while(EnumSubTypes->raw_Next(1,&subTypeGUID,0) == S_OK)
{
IEnumPStoreItemsPtr spEnumItems;
HRESULT hRes = PStore->EnumItems(0, &TypeGUID, &subTypeGUID, 0, &spEnumItems);
//Now enumerate through each of the stored entries.....
LPWSTR strWebsite;
while( spEnumItems->raw_Next(1, &strWebsite, 0) == S_OK)
{
sprintf_s(strSiteUrl, 1024, "%ws", siteName);
unsigned long psDataLen = 0;
unsigned char *psData = NULL;
char *sptr;
_PST_PROMPTINFO *pstiinfo = NULL;
//read the credentails for this website entry
hRes = PStore->ReadItem(0, &TypeGUID, &subTypeGUID, siteName, &psDataLen, &psData, pstiinfo, 0);
if( lstrlen((char *)psData)<(psDataLen-1) )
{
int i=0;
for(int m=0; m<psDataLen; m+=2)
{
if(psData[m]==0)
strSiteCredentials[i]=',';
else
strSiteCredentials[i]=psData[m];
i++;
}
strSiteCredentials[i-1]=0;
}
else
{
sprintf_s(strSiteCredentials, 1024, "%s", psData);
}
//Now decode the username & password from strSiteCredentials for different types
//5e7e8100 - IE:HTTP basic authentication based passwords
//username and passwords are seperated by ':'
if(lstrcmp(szItemGUID, "5e7e8100") ==0 )
{
strPassword[0]=0;
sptr = strstr(strSiteCredentials, ":");
if( sptr != NULL )
{
strcpy_s(strPassword, 1024, sptr+1);
*sptr = 0;
strcpy_s(strUsername, 1024, strSiteCredentials);
}
printf("n website = %S, username = %s, password = %s", strSiteUrl, strUsername, strPassword);
}
//e161255a - IE autocomplete passwords
if(lstrcmp(szItemGUID,"e161255a")==0)
{
if(strstr(strSiteUrl, "StringIndex" ) == 0 )
{
if(strstr(strSiteUrl,":String")!=0)
*strstr(strSiteUrl,":String")=0;
lstrcpyn(strPassword,strSiteUrl,8);
if( !( (strstr(strPassword,"http:/")==0)&&(strstr(strPassword,"https:/")==0) ) )
{
//username & passwords are seperated by ','
strPassword[0]=0;
sptr = strstr(strSiteCredentials,",");
if( sptr != NULL )
{
strcpy_s(strPassword, 1024, sptr+1);
*sptr = 0;
strcpy_s(strUsername, 1024, strSiteCredentials);
}
printf("n website = %s, username = %s, password = %s", strSiteUrl, strUsername, strPassword);
}
}
} //end of autocomplete if
} //inner while loop
} //middle while loop
} //top while loop
} //end of function
缩进变得很有趣(是的,我的错:)),但我不认为它会影响问题,如果你能忽略这一点的话:)
看看你的完整代码,这绝对是C++,它利用了COM(组件对象模型),更重要的是,这个库似乎对你隐藏了大部分COM的"丑陋"。话虽如此,我不确定你是否会知道IPStore真的是。
请参阅此参考资料以了解COM。特别是,请参阅图4。我怀疑IPStorePtr是一个接口指针,它允许客户端代码与客户端对话。
我还怀疑PStoreCreateInstance
是CoCreateInstance
和QueryInterface
的包装器(两者都是普通COM API的一部分)。所以在这一行代码中:
HRESULT hRes = PStoreCreateInstance(&PStore, 0, 0, 0);
hRes是PStoreCreateInstance
函数的返回状态(您应该始终检查)。另外,请注意,我们将传递PStore的地址(&PStore
)作为第一个参数。如果此函数成功,您将有一个指向COM对象上接口的指针。
在这行代码中:
hRes = PStore->EnumTypes(0, 0, &EnumPStoreTypes);
我们使用指向COM对象的指针来调用在对象CCD_ 6中定义的函数。
- 有什么方法可以包装自动类型扣除的助推"tee"流的构造?
- Qt中的包装连接方法隐藏了编译器所需的信息
- 如何将 c++ 类包装到 python 中,以便我可以使用 pybind11 访问其成员的公共方法(成员是一个对象指针)
- C++ sqrat 通过包装器绑定方法
- 如何在 C 中包装C++具有参数的类方法或返回另一个C++类的实例?
- 是否有类周围最薄的包装器来添加方法?
- 抽象包装带有异常的 C 错误处理的最佳方法
- 如何为其他类成员函数编写模板包装方法
- 为多线程环境包装 c++ new/delete 的安全/好方法
- 有没有一种方法可以在基于枚举的可变参数模板函数之间进行选择,这比将函数包装在结构中更简单
- 是否有一种方法可以让公共成员在班级外部无法解码,而无需访问包装器功能
- 在没有包装程序类的情况下,在ActiveX接口上调用方法
- 将C++转换为C#:如何包装C++中的类,使模板类中的方法在C#中的派生类中可用
- 为对象创建"thin"结构包装器的正确方法是什么?
- C# 使用包装类中的字符串参数调用 C++ 方法
- C++包装Objective-C的方法:如何为变量添加值
- 从Rcpp中的包装方法返回自定义对象
- C++中宏中的包装方法
- 如何在c#上为具有双间接参数的包装c++方法编写签名?
- 包装方法返回 c++ std::array<std::string, 4> in cython