好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

几则技巧

几则技巧 这几天帮同事解决了几个问题,写在这里作为备忘,其他朋友也可以参考。 l 建立 UNICODE 的 MFC 工程 (VC6) 。 按正常步骤建立一个 MFC 应用程序工程。 打开 : Project-Settings-C/C++ 。在 Preprocessor definitions 中定义 UNICODE 和 _UNICODE 两

几则技巧

这几天帮同事解决了几个问题,写在这里作为备忘,其他朋友也可以参考。

l 建立 UNICODE 的 MFC 工程 (VC6) 。

按正常步骤建立一个 MFC 应用程序工程。

打开 : Project->Settings…->C/C++ 。在 Preprocessor definitions 中定义 UNICODE 和 _UNICODE 两个宏。

打开 : Project->Settings…->Link 。选择 Output 类别,修改 Entry-Point Symbol 的值为 wWinMainCRTStartup 。

编译应该没有问题了。运行时若出现找不到 mfcxxx.dll ,从 VC 的安装文件中拷贝到系统目录就行了。

l DLL 内存释放问题 (VC6) 。

在 Windows 下,如果在一个 DLL 里分配的内存,在另外一个 DLL 或者在 EXE 里释放,程序可能会 crash 。这时多半是因为这些 DLL 和 EXE 链接了不同的运行库,不同运行库的堆是不同的,在一个堆里分配的内存,在另外一个堆里释放,就会 crash 。解决方案有两个:

方案一:打开 : Project->Settings…->C/C++ 。选择 Code Generation 类别,确保所有工程的 Use run-time library 的值是一致。

方案二:哪里分配就在哪里释放。 DLL 提供了分配函数,同时提供一个释放函数,这样可以确保在同一个堆里释放。

l 抽象工厂模式的一个实例。

同事在开发手机的 PC 模拟环境时,遇到这样一个问题:其可能通过串口与另外一个真实的手机通信,也可能通过 Socket 与另外一个模拟手机通信。由配置文件决定实际的通信方式。

首先自然会想到,建立一个抽象基类 Stream ,一个继承 Stream 的子类 SerialPortStream ,实现串口通信,和一个继承 Stream 的子类 SocketStream ,实现 Socket 通信。调用者通过抽象基类 Stream 的指针去调用不同子类的实现,从而避免大量 if/else 语句。

但是有好几地方都要创建这些对象,由于创建时仍然要关心具体的子类,前面的方法仍然不够完美。为了避免这些创建代码分散在不同的地方,可以采用抽象工厂模式。程序运行时,根据配置文件创建一个工厂对象,后面通过抽象工厂的指针去创建不同的子类。这样,调用者与实现者之间的耦合降到了最低。

l DBUS marshal 函数的参数个数。

DBUS 的 glib 封装的 marshal 函数,与 glib 原生的 marshal 完全一样。比如:

void

g_cclosure_marshal_VOID__INT (GClosure *closure,

GValue *return_value,

guint n_param_values,

const GValue *param_values,

gpointer invocation_hint,

gpointer marshal_data)

{

typedef void (*GMarshalFunc_VOID__INT) (gpointer data1,

gint arg_1,

gpointer data2);

register GMarshalFunc_VOID__INT callback;

register GCClosure * cc = (GCClosure*) closure;

register gpointer data1, data2;

g_return_if_fail (n_param_values == 2);

if (G_CCLOSURE_SWAP_DATA (closure))

{

data1 = closure-> data ;

data2 = g_value_peek_pointer (param_values + 0);

}

else

{

data1 = g_value_peek_pointer (param_values + 0);

data2 = closure-> data ;

}

callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc ->callback);

callback (data1,

g_marshal_value_peek_int (param_values + 1),

data2);

}

语句 g_return_if_fail (n_param_values == 2); 有些让人迷惑,明明只有一个参数,为什么参数个数是 2 个。从这个函数的实现可以看出,第一个参数始终是对象本身,虽然 signal 只有一个参数,加上对象指针本身,参数个数变成 2 个了。

l 安装 FC5 的内核源码。

[root@localhost ~]# rpm -ivh kernel-2.6.15-1.2054_FC5.src.rpm

[root@localhost ~]# cd /usr/src/redhat/SPECS

[root@localhost SPECS]# rpmbuild -bp --target=i686 kernel-2.6.spec

[root@localhost SPECS]# cd BUILD/kernel-2.6.15/linux-2.6.15.i686/

[root@localhost linux-2.6.15.i686]# make menuconfig

[root@localhost linux-2.6.15.i686]#make

[root@localhost linux-2.6.15.i686]# rm /lib/modules/2.6.15-1.2054_FC5/build

[root@localhost linux-2.6.15.i686]# ln /lib/modules/2.6.15-1.2054_FC5/build /usr/src/redhat/BUILD/kernel-2.6.15/linux-2.6.15.i686/ -s

查看更多关于几则技巧的详细内容...

  阅读:42次