??xml version="1.0" encoding="utf-8" standalone="yes"?>սƽ:C++博客-所有随W?/title><link>//www.pppqb.icu/default.html?id=-18</link><description>专注于C++技?/description><language>zh - սƵ2019|սع//www.pppqb.icu/eryar/archive/2019/08/06/animation.htmleryareryarTue, 06 Aug 2019 03:07:00 GMT//www.pppqb.icu/eryar/archive/2019/08/06/animation.html//www.pppqb.icu/eryar/comments/216643.html//www.pppqb.icu/eryar/archive/2019/08/06/animation.html#Feedback0//www.pppqb.icu/eryar/comments/commentRss/216643.html//www.pppqb.icu/eryar/services/trackbacks/216643.htmlOpenCASCADE动画功能

 

eryar@163.com


1.Introduction

OpenCASCADE提供了类AIS_Animation{来实现单的动画功能?/span>

 

从其cd可以看出Q动d能有两种Q一U是相机的动?/span>AnimationCameraQ一U是模型的动?/span>AnimationObject。因?/span>OpenCASCADE不像OpenSceneGraph那样是专门做仿真动画的,内置多线E,OpenCASCADE中的动画可以理解Z?/span>while(true) {update();}Q即在动L间内对相机或模型的v始位|和l止位置q行插值ƈ更新来实现动甅R对于简单的动画效果Q这U方式是够用了?/span>

 

2. Examples

?/span>OpenCASCADE的源码文件夹中提供了动画用法的示例,分别演示了模型变换、视囑֏换及动M存成视频文gQ当然这个功能需要引入第三方?/span>FFmpegQ?/span>

OpenCASCADE中动M间位|的生成采用了类gp_TrsfNLerpq行插倹{?/span>

 Ҏ其注释是对一个变换的三个部分分别q行U性插|旋{部分采用四元数类q行插倹{这U插值方式不可能满复杂动画的要求,不过可以把这个类当成一个插值的例子?/span>

?/span>Draw Test Harness中输入以下命令:

source tests/v3d/anim/propeller

vanim anim -play -playSpeed 0.1

卛_以让一个螺旋桨动v来了Q?/span>

其实q个螺旋桨动L个复杂的例子Q包含了视图动画和模型动甅R对于简单的CZQ可以参考另外几个文Ӟ里面的例子是相对单的?/span>

 

3. Conclusion

OpenCASCADE7.3版本中引入了单动ȝ功能Q结合其试案例Q找到其实现源码Q可以方便地在程序中实现单的动画功能。其中动L持两U方式:一U是视图支画Q一U是模型动画。视囑֊M般用于两个视图之间的动画q渡Q如从主视图切换CԒ视图中间加一个动画过渡;模型动画可用于简单的动画仿真?/span>

 

 

 

 

 

 

 

 



eryar 2019-08-06 11:07 发表评论
]]>
QPushButton动态更新QML中Image囄 - սƵ2019|սع//www.pppqb.icu/gaimor/archive/2019/08/05/216635.htmlccsdu2009ccsdu2009Mon, 05 Aug 2019 03:37:00 GMT//www.pppqb.icu/gaimor/archive/2019/08/05/216635.html//www.pppqb.icu/gaimor/comments/216635.html//www.pppqb.icu/gaimor/archive/2019/08/05/216635.html#Feedback0//www.pppqb.icu/gaimor/comments/commentRss/216635.html//www.pppqb.icu/gaimor/services/trackbacks/216635.html QML
import QtQuick 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2

Column 
{
    width
:640
    height:400
    
    Image 
    { 
        id:image
        width:640
        cache: false
        source: "image://colors/red" 
    
}
    
    Connections
    
{
        target
: imagecontext
        onCallQmlRefeshImg:
        {
            image.source = ""
            image.source = "image://imageprovider"
            console.log("refresh.")
;
        
}
    }    
}
ImageProvider
class ColorImageProvider : public QQuickImageProvider
{
public:
    ColorImageProvider()
        : QQuickImageProvider(QQuickImageProvider::Pixmap)
    {
    }

    QPixmap requestPixmap(
const QString &id, QSize *size, const QSize &requestedSize) override
    {
        
int width = 100;
        
int height = 50;

        
if (size)
            
*size = QSize(width, height);
        QPixmap pixmap(requestedSize.width() 
> 0 ? requestedSize.width() : width,
            requestedSize.height() 
> 0 ? requestedSize.height() : height);
        pixmap.fill(QColor(id).rgba());
        
return pixmap;
    }
};

class ImageProvider : public QQuickImageProvider
{
public:
    ImageProvider::ImageProvider(ImageType type, Flags flags 
= Flags()) :
        QQuickImageProvider(type, flags)
    {
    }
    
    
~ImageProvider(){}

    QImage ImageProvider::requestImage(
const QString &id, QSize *size, const QSize &requestedSize)
    {
        
return image;
    }

    QImage image;
};

ImageContext
class ImageContext : public QObject
{
    Q_OBJECT
public:
    ImageContext(QObject
* parent = 0);
    ImageProvider
* m_imageProvider = nullptr;
public slots:
    
void setImage(const QImage& image);
signals:
    
void callQmlRefeshImg();
};
ImageContext::ImageContext(QObject* parent):
QObject(parent)
{
    m_imageProvider 
= new ImageProvider(QQuickImageProvider::Image);
}

void ImageContext::setImage(const QImage& image)
{
    m_imageProvider
->image = image;
    emit callQmlRefeshImg();
}

注册和相?/span>
    qml->engine()->addImageProvider(QLatin1String("colors"),new ColorImageProvider);
    ImageContext
* context = new ImageContext(this);
    qml
->engine()->rootContext()->setContextProperty("imagecontext",context);
    qml
->engine()->addImageProvider(QLatin1String("imageprovider"),context->m_imageProvider);

    qml
->setSource(QUrl("image.qml"));

    QDir dir(
"E:/MyVideoPlayer/Win32/Release/capture");

    QStringList files 
= dir.entryList(QDir::Files,QDir::SortFlag::Time | QDir::SortFlag::Reversed);
    qDebug() 
<< "files:" << files.size();
    
    connect(button, 
&QPushButton::clicked,[=]()
       {
           
static int current = 0;
           auto list 
= qml->rootObject()->childItems();
           
if(current == files.size())
               current 
= 0;

           QImage image;
           QString file 
= QString("E:/MyVideoPlayer/Win32/Release/capture/"+ files.at(current);
           qDebug() 
<< "loaded:" << image.load(file) << "," << file<<","<<current;
           context
->setImage(image);

           current
++;
       }
    );



ccsdu2009 2019-08-05 11:37 发表评论
]]>
?C++ 中实C个轻量的标记清除 gc pȝ(转蝲) - սƵ2019|սع//www.pppqb.icu/Khan/archive/2019/08/01/gc_system_for_cpp.htmlKhanKhanThu, 01 Aug 2019 02:57:00 GMT//www.pppqb.icu/Khan/archive/2019/08/01/gc_system_for_cpp.html//www.pppqb.icu/Khan/comments/216620.html//www.pppqb.icu/Khan/archive/2019/08/01/gc_system_for_cpp.html#Feedback0//www.pppqb.icu/Khan/comments/commentRss/216620.html//www.pppqb.icu/Khan/services/trackbacks/216620.html# ?C++ 中实C个轻量的标记清除 gc pȝ
[引用](https://blog.codingnow.com/2010/02/cpp_gc.html)
最q想?engine 做一个简?C++ 装Q结?QT 使用。engine 本n是用U?C 实现的,大部分应用基?lua 开发。对对象生命期管理也依赖 lua ?gc pȝ。关于这部分的设计,可以参考我以前写的一??lua 装 C 对象的生存期理问题 ?br />
当我们把中间层搬?C++ 中时Q遇到的问题之一是QC++ 没有原生?gc 支持。我也曾l写q一?gc 库。但在特定应用下q不够简z。这几天q年休息Q仔l考虑了一下相关的需求,试实现了一个更单的 gc 框架。不?200 行代码吧Q我直接列在q篇 blog 里?br />
q些是一些玩具代码,我花了一天时间来写。有许多考虑不周的地方,以及不完整的功能。但可以阐明一些基本思\?br />
首先我需要一个`标记清除`?`gcpȝ`Q用来解决`引用记数`不容易解决的`循环引用`问题。它的实Cx`引用记数`复杂太多Qƈ有相同甚x高的性能?br />
我不想用复杂的 template 技术,利用太多的语法糖让用看h单。如果需要让q些 C++ 代码看v来更CQ更?#8220;品味”Q我想也不是很难的事情?br />
接口和实现希望尽量分,对用的h暴露细节。但不拘泥于教条Q强求做成类?COM 那样的通用 ABI 。还是尽量利?C++ 语言本n提供的机Ӟ不滥用?br />
使用量单,不要让用h员有太大负担?br />
功能满最低需求即可。代码容易阅读,使用人员可以很快理解原理Q不至于误用。也方便日后扩展以适应新的需求?br />
代码如下Q?/div>
 1 /* 
 2  * filename: i_gcobject.h 
 3  * Copyright (c) 2010 ,
 4  * Cloud Wu . All rights reserved. 
 5  * 
 6  * //www.codingnow.com 
 7  * 
 8  * Use, modification and distribution are subject to the "New BSD License" 
 9  * as listed at . 
10  */ 
11   
12 #ifndef interfacce_gcobject_h 
13 #define interfacce_gcobject_h 
14 
15 #define interface struct 
16 
17 interface i_gcobject { 
18     virtual ~i_gcobject() {} 
19 
20     virtual void touch() {} 
21 
22     virtual void mark() = 0 ; 
23     virtual void grab() = 0 ; 
24     virtual void release() = 0 ; 
25 
26     static void collect(); 
27 }; 
28 #endif

所有支?`gc理的接口`都承至 `i_gcobject` Q提供三个方?
* mark 可以把这个对象打上标讎ͼ被标记的对象不会被 collect 回收?/div>
* grab 对象挂接到一个被U呼?root 的特D?gcobject 上?/div>
* release 对象从 root 上取掉?br />
另提?touch 的模板方法供 mark 回调Q用来标记同一对象中的不同部分?/div>
mark Ҏ一般在 touch Ҏ中用,另外Qcollect Ҏ主动调?root ?mark ?br />
 1 /*  filename: i_gcholder.h
 2  *  Copyright (c) 2010 ,
 3  *      Cloud Wu . All rights reserved.
 4  *
 5  *      //www.codingnow.com
 6  *
 7  *  Use, modification and distribution are subject to the "New BSD License"
 8  *  as listed at <url: //www.opensource.org/licenses/bsd-license.php >.
 9  */
10 
11 #ifndef interfacce_gcholder_h
12 #define interfacce_gcholder_h
13 
14 #include "i_gcobject.h"
15 
16 interface i_gcholder : virtual i_gcobject {
17   virtual void hold(i_gcobject *) = 0;
18   virtual void unhold(i_gcobject *) = 0;
19   
20   static i_gcholder * create();
21 };
22 #endif
`i_gcholder` ?root 的接口,提供 `hold` ?`unhold` Ҏ来挂接需要持久保留的 gcobject ?br />
 1 /*  filename: i_gcobject.h
 2  *  Copyright (c) 2010 ,
 3  *      Cloud Wu . All rights reserved.
 4  *
 5  *      //www.codingnow.com
 6  *
 7  *  Use, modification and distribution are subject to the "New BSD License"
 8  *  as listed at <url: //www.opensource.org/licenses/bsd-license.php >.
 9  */
10 
11 #ifndef interfacce_gcobject_h
12 #define interfacce_gcobject_h
13 #define interface struct
14 
15 interface i_gcobject {
16 
17   virtual ~i_gcobject() {}
18 
19   virtual void touch() {}
20 
21   virtual void mark() = 0 ;
22   virtual void grab() = 0 ;
23   virtual void release() = 0 ;
24 
25   static void collect();
26 };
27 #endif
 1 /*  filename: gcobject.h
 2  *  Copyright (c) 2010 ,
 3  *      Cloud Wu . All rights reserved.
 4  *
 5  *      //www.codingnow.com
 6  *
 7  *  Use, modification and distribution are subject to the "New BSD License"
 8  *  as listed at <url: //www.opensource.org/licenses/bsd-license.php >.
 9  */
10 
11 #ifndef gc_object_h
12 #define gc_object_h
13 
14 #include "i_gcobject.h"
15 
16 class gcobject : virtual i_gcobject {
17   bool marked;
18 
19 public:
20   gcobject();
21 
22   virtual void mark();
23   virtual void grab();
24   virtual void release();
25 
26   struct f_unmarked;
27 
28 };
29 #endif
30 ```
31 
32 ```c++
33 /*  filename: gcobject.cpp 
34  *  Copyright (c) 2010 ,
35  *      Cloud Wu . All rights reserved.
36  *
37  *      //www.codingnow.com
38  *
39  *  Use, modification and distribution are subject to the "New BSD License"
40  *  as listed at <url: //www.opensource.org/licenses/bsd-license.php >.
41  */
42 
43 #include "gcobject.h"
44 #include "i_gcholder.h"
45 #include <vector>
46 #include <algorithm>
47 
48 static bool gc_trigger;
49 static std::vector<gcobject *> gc_pool;
50 static i_gcholder * gc_root = i_gcholder::create();
51 
52 
53 struct gcobject::f_unmarked {
54   bool operator() (gcobject * value) {
55     bool unmarked = value->marked != gc_trigger;
56     if (unmarked) {
57       delete value;
58     }
59     return unmarked;
60   }
61 };
62 
63 gcobject::gcobject() : marked(!gc_trigger) {
64   gc_pool.push_back(this);
65 }
66 
67 void gcobject::mark() {
68   if (marked != gc_trigger) {
69     marked = gc_trigger;
70     touch();
71   }
72 }
73 
74 void gcobject::grab(){
75   gc_root->hold(this);
76 }
77 
78 void gcobject::release(){
79   gc_root->unhold(this);
80 }
81 
82 void i_gcobject::collect() {
83   gc_root->mark();
84   gc_pool.erase(remove_if(gc_pool.begin(), gc_pool.end() , gcobject::f_unmarked()), gc_pool.end());
85   gc_trigger = !gc_trigger;
86 }
gcobject 为具体的 gc 实现Q实C `mark` 、`grab`、`release` ?`collect` Ҏ?/div>
`mark` 采用的直接向一 bool 变量讄标记。这个标记利用了 `trigger` q个乒乓开养I每次 `collect` 都会切换状态?/div>
`grab` ?`release` 可以把对象挂接到 root 上,或从上取掉?/div>
`collect` 会主动从 root 开?`mark` Qƈ释放那些没有 `mark` 的对象?br />
 1 /*  filename: gcholder.cpp
 2  *  Copyright (c) 2010 ,
 3  *      Cloud Wu . All rights reserved.
 4  *
 5  *      //www.codingnow.com
 6  *
 7  *  Use, modification and distribution are subject to the "New BSD License"
 8  *  as listed at <url: //www.opensource.org/licenses/bsd-license.php >.
 9  */
10 
11 #include "i_gcholder.h"
12 #include "gcobject.h"
13 #include <vector>
14 #include <algorithm>
15 #include <cassert>
16 
17 class gcholder : public virtual i_gcholder, virtual gcobject {
18   std::vector<i_gcobject *> hold_set;
19   std::vector<i_gcobject *> unhold_set;
20 
21   bool set_changed;
22   bool hold_set_sorted;
23   bool unhold_set_sorted;
24 
25   void combine_set();
26   virtual void touch();
27 
28   virtual void hold(i_gcobject *obj) {
29     hold_set.push_back(obj);
30     hold_set_sorted = false;
31     set_changed = true;
32   }
33 
34   virtual void unhold(i_gcobject *obj) {
35     unhold_set.push_back(obj);
36     unhold_set_sorted = false;
37     set_changed = true;
38   }
39 
40   struct f_mark {
41     void operator() (i_gcobject *obj) {
42       obj->mark();
43     }
44   };
45 
46 public:
47 
48   gcholder() :  set_changed(false),  hold_set_sorted(true) ,  unhold_set_sorted(true) {  }
49 
50 };
51 
52 void gcholder::combine_set(){
53   if (!hold_set_sorted) {
54     std::sort(hold_set.begin(),hold_set.end());
55     hold_set_sorted = true;
56   }
57   if (!unhold_set_sorted) {
58     std::sort(unhold_set.begin(),unhold_set.end());
59     unhold_set_sorted = true;
60   }
61   if (!unhold_set.empty()) {
62     std::vector<i_gcobject *>::iterator iter1 = hold_set.begin();
63     std::vector<i_gcobject *>::iterator iter2 = unhold_set.begin();
64     while (iter1 != hold_set.end() && iter2 != unhold_set.end()) {
65       if (*iter1 == *iter2) {
66         *iter1 = NULL;
67         ++iter1;
68         ++iter2;
69       } else {
70         assert(*iter1 < *iter2);
71         ++iter1;
72       }
73     }
74     i_gcobject * null = NULL;
75     hold_set.erase(std::remove(hold_set.begin(),hold_set.end(),null) , hold_set.end());
76     unhold_set.clear();
77   }
78 }
79 
80 void gcholder::touch(){
81   if (set_changed) {
82     combine_set();
83     set_changed = false;
84   }
85   std::for_each(hold_set.begin(), hold_set.end(), f_mark());
86 }
87 
88 i_gcholder * i_gcholder::create(){
89   return new gcholder;
90 }


gcholder 理论上可以有多个实例Qƈ怺挂接。(否则不需要承至 i_gcobject Q这个设计可以用来模拟多U的堆栈。但实际上ƈ不需要这么复杂。因为在大部分应用里Q如果你的程序有一个周期性的d@环,可以不?gc pȝ里模拟出一个多U的堆栈。我们只用在循环之外?collect 卛_。再堆栈调用的较深层ơ触?collect 反而效果不佻I会导致许多?gc 对象无法回收?/div>
最后来看一个玩具代码,?stl 里的 mutliset 实现了一个简单的树接口。可能没有什么用h|但它演示了一个较复杂的对象相互引用的关系。ƈ可以展示 gc 如何正确工作?/div>

 1 /*  filename: test.cpp
 2  *  Copyright (c) 2010 ,
 3  *      Cloud Wu . All rights reserved.
 4  *
 5  *      //www.codingnow.com
 6  *
 7  *  Use, modification and distribution are subject to the "New BSD License"
 8  *  as listed at <url: //www.opensource.org/licenses/bsd-license.php >.
 9  */
10 #include "gcobject.h"
11 #include <cstdio>
12 #include <set>
13 #include <algorithm>
14 
15 interface i_tree : virtual i_gcobject {
16   virtual void link(i_tree *p) = 0;
17   static i_tree * create();
18 };
19 
20 class tree : public virtual i_tree , virtual gcobject {
21   tree *parent;
22   std::multiset<tree *> children;
23   struct f_mark {
24     void operator() (tree *node) {
25       node->mark();
26     }
27   };
28 
29   virtual void touch() {
30     if (parent)
31       parent->mark();
32     std::for_each(children.begin(), children.end(), f_mark());
33   }
34 
35   void unlink();
36   virtual void link(i_tree *parent);
37 
38 public:
39   tree() : parent(NULL) {
40     printf("create node %p\n",this);
41   }
42 
43   ~tree() {
44     printf("release node %p\n",this);
45   }
46 
47 };
48 
49 
50 void tree::unlink() {
51   if (parent) {
52     parent->children.erase(this);
53     parent = NULL;
54   }
55 }
56 
57 void tree::link(i_tree *p){
58   unlink();
59   if (p) {
60     tree * cp = dynamic_cast<tree *>(p);
61     cp->children.insert(this);
62     parent = cp;
63   }
64 }
65 
66 i_tree *i_tree::create(){
67   return new tree;
68 }
69 
70 int main(){
71   i_tree *root = i_tree::create();
72   root->grab();
73   i_tree *node;
74   node = i_tree::create();
75   node->link(root);
76   node = i_tree::create();
77   node->link(root);
78   i_gcobject::collect();
79   printf("collected\n");
80   node->link(NULL);
81   i_gcobject::collect();
82   printf("finalize\n");
83   root->release();
84   i_gcobject::collect();
85   return 0;
86 }
我们在实C个基?gc 的对象时Q可以先定义出需要的接口Q让接口?i_gcobject l承。例如上例中?i_tree ?/div>
然后在实现这个接口时Q可以虚l承 gcobject 。例如上例中?tree ?/div>
如果有需要,重?touch ҎQ在 touch Ҏ?mark 相关?gcobject 。对?tree q个例子Q就是调用父亲和孩子节点?mark ?/div>
对象依然可以写析构函敎ͼ相当于对象的 finalize 。在析构函数中,不要再释攑֒它相关的 gcobject Q那些留l?gc pȝd成。(例如?tree 里,׃要在 ~tree ?delete children 容器中的变量Q也不需要把自己从父亲节点上摘掉Q?/div>
如果仅仅只是使用那些接口Q则不需要再包含 gcobject.h Q因?gcobject 的细节只供实?i_gcobject 时用?/div>

Khan 2019-08-01 10:57 发表评论
]]>ERROR: Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve androidx.appcompat:appcompat:*** - սƵ2019|սع//www.pppqb.icu/jack-wang/archive/2019/08/01/216617.htmlWed, 31 Jul 2019 17:55:00 GMT//www.pppqb.icu/jack-wang/archive/2019/08/01/216617.html//www.pppqb.icu/jack-wang/comments/216617.html//www.pppqb.icu/jack-wang/archive/2019/08/01/216617.html#Feedback0//www.pppqb.icu/jack-wang/comments/commentRss/216617.html//www.pppqb.icu/jack-wang/services/trackbacks/216617.html

2019-08-01 01:55 发表评论
]]>
使用CString GetBuffer自适应获取计算机名U?/title><link>//www.pppqb.icu/qinqing1984/archive/2019/07/31/216616.html</link><dc:creator>春秋十二?/dc:creator><author>春秋十二?/author><pubDate>Wed, 31 Jul 2019 04:51:00 GMT</pubDate><guid>//www.pppqb.icu/qinqing1984/archive/2019/07/31/216616.html</guid><wfw:comment>//www.pppqb.icu/qinqing1984/comments/216616.html</wfw:comment><comments>//www.pppqb.icu/qinqing1984/archive/2019/07/31/216616.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>//www.pppqb.icu/qinqing1984/comments/commentRss/216616.html</wfw:commentRss><trackback:ping>//www.pppqb.icu/qinqing1984/services/trackbacks/216616.html</trackback:ping><description><![CDATA[   Z减少E序中的编码,灉|按需理字符串空_使用了ATL中的CStringc,代码如下<br /> <div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> //www.CodeHighlighter.com/<br /> <br /> --><span style="color: #008080; "> 1</span>         CString bstrComPathName;<br /> <span style="color: #008080; "> 2</span>         WCHAR componentPathName[1];<br /> <span style="color: #008080; "> 3</span>         DWORD dwNameLen = 1;    <br /> <span style="color: #008080; "> 4</span> <br /> <span style="color: #008080; "> 5</span>         <span style="color: #0000FF; ">if</span> (!GetComputerNameEx(<span style="color: #ff00ff;">ComputerNamePhysicalDnsFullyQualified</span>, componentPathName, &dwNameLen))<br /> <span style="color: #008080; "> 6</span>         { <br /> <span style="color: #008080; "> 7</span>             DWORD dwErr = GetLastError();<br /> <span style="color: #008080; "> 8</span>             <span style="color: #0000FF; ">if</span>(<span style="color: #ff0000;">ERROR_MORE_DATA</span>==dwErr)<br /> <span style="color: #008080; "> 9</span>             {            <br /> <span style="color: #008080; ">10</span>                 <span style="color: #0000FF; ">if</span> (!GetComputerNameEx(ComputerNamePhysicalDnsFullyQualified, bstrComPathName.<span style="color: #993366;"><strong class="dpun">GetBuffer</strong></span>(dwNameLen), &dwNameLen))<br /> <span style="color: #008080; ">11</span>                 { <br /> <span style="color: #008080; ">12</span>                     zlog_error(g_zc, "GetComputerNameEx with ComputerNamePhysicalDnsFullyQualified fail: %d", GetLastError());<br /> <span style="color: #008080; ">13</span>                     <span style="color: #0000FF; ">return</span> -1;<br /> <span style="color: #008080; ">14</span>                 }<br /> <span style="color: #008080; ">15</span>             }<br /> <span style="color: #008080; ">16</span>             <span style="color: #0000FF; ">else</span><br /> <span style="color: #008080; ">17</span>             {<br /> <span style="color: #008080; ">18</span>                 zlog_error(g_zc, "GetComputerNameEx with ComputerNamePhysicalDnsFullyQualified for fail: %d", dwErr);<br /> <span style="color: #008080; ">19</span>                 <span style="color: #0000FF; ">return</span> -1;<br /> <span style="color: #008080; ">20</span>             }<br /> <span style="color: #008080; ">21</span>         }                <br /> <span style="color: #008080; ">22</span>         bstrComPathName.<span style="color: #993366;"><strong class="dpun">ReleaseBuffer</strong></span>(); </div>     需要注意的是,GetBufferҎ虽提供方便了直接修改CString对象的内部缓冲区Q但q背了面向对象设计的原则Q由公开Ҏ修改内部数据Q,因此不保证对象的完整性,在操作完成后一定要调用ReleaseBuffer<img src ="//www.pppqb.icu/qinqing1984/aggbug/216616.html" width = "1" height = "1" /><br><br><div align=right><a href="//www.pppqb.icu/" title="սƵ2019">սƵ2019</a></div>]]></description></item></channel></rss> <script>(function(){ var src = (document.location.protocol == "") ? "//js.passport.qihucdn.com/11.0.1.js?9ed1f3a8f9c3ff069b7b95c01474c743":"https://jspassport.ssl.qhimg.com/11.0.1.js?9ed1f3a8f9c3ff069b7b95c01474c743"; document.write('<script src="' + src + '" id="sozz"><\/script>'); })(); </script>