2008年4月24日星期四

VS2008创建wxwidget 项目

尝试用vs2008 express版学习wxwidget。建立了一个helloworld都没能链接成功。照网上的文章做了也不行。最后还是参照其自带的samples把项目属性设置成功了。至于以前设置的错误,希望随着时间的积累能够原因。步骤大致如下:
1,把wxWidget安装到 D:\wxWidgets-2.8.7。设置环境变量WXWIN=D:\wxWidgets-2.8.7。
2,用vs2008打开D:\wxWidgets-2.8.7\build\msw\wx.dsw,编译所有代码。
3,可以另起一个solution,创建一个空项目。
4,把helloworld程序past进去。
5,设置项目属性:
additional include directories: "$(WXWIN)\lib\vc_lib\mswd";"$(WXWIN)\include"
preprocessor: WIN32;_DEBUG;__WXMSW__;__WXDEBUG__;_WINDOWS;NOPCH
additional library directories: $(WXWIN)\lib\vc_lib

错误的版本加入了一些其它头文件路径。

2008年4月18日星期五

对google BLOG HTML代码的修改。

1)使用默认的模版代码,不能在IE下浏览。据说是因为编码的问题。把<$BlogMetaData$>放到head标签后面。


2)现在都是宽屏的显示器了。模版中的正文宽度太狭窄了,调宽:
把所有width:700px的地方都换成900px, 因为模版中content图片的宽度是固定的 900所以去调下面粗体部分。
#main-content {
width:900px;
background:#FFF3DB url("http://www.blogblog.com/scribe/bg_paper_mid.jpg") repeat-y;
margin:0;
text-align:left;
display:block;
}

@media all {
#main {
width:630px; // 由原来的430改为630。
float:right;
padding:8px 0;
margin:0;
}
这样整个content布局宽度增加了200pix。

理解libjingle的ThreadManager

Thread Local Storage(TLS)的作用。
进程中的所有线程共享进程的虚拟地址空间。方法中的局部变量对于每个运行这个方法的线程是独立唯一的。但是,全局的静态变量是被这个进程中的所有线程共享的。通过使用TLS你可以为每个线程提供独立的数据。

一般在process初始化时分配tls Index。这样随后这个process中的线程就可以通过这个index存储与每个线程自己相关的数据了。
msdn关于TlsAlloc()的说明:
Allocates a thread local storage (TLS) index. Any thread of the process can subsequently use this index to store and retrieve values that are local to the thread, because each thread receives its own slot for the index.
If the function succeeds, the return value is a TLS index. The slots for the index are initialized to zero.
The threads of the process can use the TLS index in subsequent calls to the TlsFree, TlsSetValue, or TlsGetValue functions. The value of the TLS index should be treated as an opaque value; do not assume that it is an index into a zero-based array
TLS indexes are typically allocated during process or dynamic-link library (DLL) initialization. After a TLS index has been allocated, each thread of the process can use it to access its own TLS storage slot. To store a value in its TLS slot, a thread specifies the index in a call to TlsSetValue. The thread specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.
TLS indexes are not valid across process boundaries. A DLL cannot assume that an index assigned in one process is valid in another process.


libjingel中的ThreadManager。
这个类完成对所有Thread实例线程的管理。其中就分配了一个slot index用于保存current thread。

ThreadManager使用ScriticalSecion,ScriticalSection相当于java中的synchronize中使用的锁。
windows使用CRITICAL_SECTION 定义锁。POSIX使用pthread_mutex_t。
相应的方法分别是:
windows: InitializeCriticalSection(&crit_)、EnterCriticalSection(&crit_)、 LeaveCriticalSection(&crit_)、DeleteCriticalSection(&crit_)。
POSIX: pthread_mutex_init()、pthread_mutex_lock(&mutex_)、 pthread_mutex_destroy(&mutex_)、 pthread_mutex_unlock(&mutex_)
ScriticalScope则相当于java中的synchronize块。

CreateThread
Widows 下创建线程的签名。 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread);
lpStartAddr是线程运行起始地址,函数指针。lpvThreadParam为函数的参数。
thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreRun, this, flags, NULL);
void *Thread::PreRun(void *pv) {
Thread *thread = (Thread *)pv;
ThreadManager::SetCurrent(thread); // 此处把thread放到了TLS中了。
thread->Run();
return NULL;
}


[都怀疑java的native code是不是都是用了ACE的东西了,至少思路该是一样的吧。]

2008年4月13日星期日

sigslot in libjingle

The libjingle depends on the sigslot very much. From the Pattern's view, the signal-slot follows the Observer pattern.
To use the sigslot, there are 3 steps.
1) Define a Sender. The sender has a signal.
2) Of course, there's a Receiver which extends from the sigslot::slot. The receiver is the slot.
3) Somewhere, there must be a method that will connect the Sender's signal to the Receiver's slot(s) by calling the signal's connect method.
SignalA maybe is defined like this: sigslot::signal2 SignalA;
aReceiver is an object whose class inherits from sigslot::has_slots<>
aFunctionPointer is the processor of a signal. In this case, this processor method need two parameters.
Connect the signalA with the receiver's function just like this:
SignalA.connect(aReceiver , aFunctionPointer);

Reviewed these C++ keywords/concept today.
extern explicit "const member function"