正确编写c / c ++代码的ctypes包装器的方法

时间:2016-01-08 16:46:59

标签: python c++ c ctypes

感谢您花时间阅读,我希望,回答:)

我将首先解释我为尝试纠正问题所做的研究,只是为了给出一些背景知识。我也认为自己有相当强大的python知识。

我已经查找了DLL / 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,我知道第一个单词(变量?)想要成为一个指针,但不止于此我迷失了。希望有人能理解我的要求:)

以下完整代码:

#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

缩进变得有趣(是的,我的错:)),但我不相信它会影响这个问题,如果你可以如此善意地忽略这一点:)

1 个答案:

答案 0 :(得分:0)

查看完整的代码,这绝对是C ++,并且它使用了COM(组件对象模型),而且,看起来该库隐藏了大部分COM'丑陋'。话虽如此,我不确定你是否会知道IPStore确实存在。

查看this reference以了解COM的介绍。特别是,请看图4.我怀疑IPStorePtr是一个接口指针,它允许客户端代码与客户端通信。

我还怀疑PStoreCreateInstanceCoCreateInstanceQueryInterface的包装(两者都是普通COM API的一部分)。所以在这行代码中:

HRESULT hRes = PStoreCreateInstance(&PStore, 0, 0, 0); 

hRes是PStoreCreateInstance函数的返回状态(您应该始终检查)。另外,请注意我们将PStore(&PStore)的地址作为第一个参数传递。如果此函数成功,您将有一个指向COM对象上的接口的指针。

在这行代码中:

hRes = PStore->EnumTypes(0, 0, &EnumPStoreTypes);

我们使用指向COM对象的指针来调用对象EnumTypes中定义的函数。