我是一名试图学习C++ 11的C#开发人员.我正在尝试使用windns.h查询DNS.
我开始DnsQuery()
并阅读,我需要释放结果记录输出参数DnsRecordListFree()
.C#方式可能是使用try-finally
块来确保我释放资源,无论如何.
但是我了解到没有finally
阻塞,并且windns.h真的应该与时俱进并实现符合RAII标准的接口(据我理解的典型建议).我试图创建一个RAII包装器类,而不是等待它发生,我试图使用析构函数调用DnsRecordListFree()
并使用运算符重载转换来获取原始指针.
但我对如何正确使用此句柄或指针获取out参数感到困惑.在我研究的过程中,我学会了如何unique_ptr
(我已经学过一些东西)可以与自定义删除器一起使用.
所以这是我迄今为止的简单代码.可能更多的错误不仅仅是这个,但我想我可以声明另一个PDNS_RECORD *presult
并使用它作为out参数然后复制或移动或以其他方式将其值分配给a unique_ptr
,但这听起来像是太多的工作/混乱.
在我看来,unique_ptr
内部指针应该初始化为NULL
,我应该能够以某种方式将指针的地址传递给out参数,这DNSQuery
将更新原始值,当unique_ptr
我的函数中的范围超出范围时,DnsRecordListFree()
调用将自动制作.我不知道为了最小的正确/安全使用找出正确的组合.
#include#include #include #include #include using namespace std; auto pdnsDeleter = [&](PDNS_RECORD *ptr){ if (ptr) DnsRecordListFree(ptr); }; int main(int argc, char **argv) { cout << "Hello World\n"; std::unique_ptr results(0, pdnsDeleter); if (DnsQuery(L"google.com", DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, ??results??, NULL)) { cout << "google.com -> " << ??results??; } cout << "Done\n"; getchar(); return 0; }
谢谢!
您可以花一整天时间尝试调整标准智能指针,或者您可以自己编写.他们并不难做,特别是如果你愿意作弊并允许访问原始指针本身.
struct DnsRAII { PDNS_RECORD p; DnsRAII() : p(NULL) { } ~DnsRAII() { if (p != NULL) DnsRecordListFree(p, DnsFreeRecordList); } }; DnsRAII results; if (DnsQuery(L"google.com", DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &results.p, NULL)) // ...