posts - 16,  comments - 34,  trackbacks - 0
共10页: 1 2 3 4 5 6 7 8 9 Last 
re: 关于“UI线程” OwnWaterloo 2013-05-12 01:50
一方面。。。
Windows的某些函数(忘记是哪些了。。。 应该有CreateWindow) 确实会导致线程被额外分配一些内容(也忘记是哪些了。。。比如消息队列)。
Cookie也确实有Expires和Max-Age。

某些库、框架里的各种概念(UI线程,进程共享Cookie)的起源也许就源自这些区别。这些库的作者(很有可能)清楚这些区别。
在MFC或WinINet(这是个啥东西。。。)的上下文中说这些自创的概念也应该没什么问题。
无意间忘记带上术语的上下文也情有可原。。。


而另一方面。。。
确实存在很多人,对更专有的概念与更一般的概念不加区分,甚至自以为是,甚至还以此嘲笑他人。。。
对这种井底之娃,你能拿他们怎么办嘛。。。
怎么开始做这方面的事了?

话说,php,jsp还有你这里演示的一些asp代码。。。 不都是一回事么。。。
都是在html里增加一些标记。。。 给人的感觉不好。。。

这些功能,需要这么多文件,以及这么多次鼠标点击!?才能实现?
当然,我在这方面也是个菜,这也只是凭着对MS一贯的感觉来的。。。
re: EXE导出函数 OwnWaterloo 2012-12-06 22:41
@zuhd
cppblog的排版功能太弱了。。。 写东西很费劲。。。
re: EXE导出函数 OwnWaterloo 2012-12-05 14:28
@zuhd
我记得是只与文件类型(PE中的那个域)有关,与加载方式(隐式加载/显式加载)无关。

只要文件类型是exe,加载器就不会去处理重定项。
如果exe没有加载到首选基地址,里面的指令操作的就不是预想中的地址。

前面说loadlibrary的意思是:这是一种让dll/exe无法加载到首选基地址的方法。
如果将dll/exe文件复制一份(文件各种信息都是相同的),然后用loadlibrary加载这两者,那两者之一肯定之多有一个是被加载到首选基地址。于是就可以观察另一个的情况了。

但前面为了偷懒。。。 就没有用这个方法,而是用/base:0x400000 —— 这个是exe文件默认的基地址 —— 让dll无法加载到首选基地址。
re: EXE导出函数 OwnWaterloo 2012-12-04 16:13
本来应该用高级评论将重点高亮的,但不知道cppblog出了什么问题用不了。只能眼睛尖点了。。。

1. test files

module.c 导出1个变量与3个函数

__declspec(dllexport) int error_code;
__declspec(dllexport) int get(void) { return error_code; }
__declspec(dllexport) void set(int x) { error_code = x; }
int main(void) { return 0; }

main.c 输出变量地址、函数地址以及函数包含的指令

#include <stdio.h>

__declspec(dllimport) int error_code;
__declspec(dllimport) int get(void);
__declspec(dllimport) void set(int x);

int main(void)
{
int i;
unsigned char const* p;

printf("%p\n", (void*)&error_code);

p = (unsigned char*)get;
printf("%p:", p);
for (i=0; i<12; ++i) printf(" %02X", p[i]);
printf("\n");

p = (unsigned char*)set;
printf("%p:", p);
for (i=0; i<12; ++i) printf(" %02X", p[i]);
printf("\n");

return 0;
}


2. dll

编译
cl /LD /O1 module.c /link /noentry

查看首选基地址
dumpbin /all module.dll | find /i "image base"
10000000 image base (10000000 to 10004FFF)

查看反汇编与重定项
dumpbin /disasm /relocations module.dll

File Type: DLL

10001000: A1 00 30 00 10 mov eax,dword ptr ds:[10003000h]
10001005: C3 ret
10001006: 8B 44 24 04 mov eax,dword ptr [esp+4]
1000100A: A3 00 30 00 10 mov dword ptr ds:[10003000h],eax
1000100F: C3 ret

BASE RELOCATIONS #4
1000 RVA, C SizeOfBlock
1 HIGHLOW 10003000
B HIGHLOW 10003000

10001000 处(get的第1条)指令的操作数(地址在10001001)是 10003000
1000100A 处(set的第2条)指令的操作数(地址在1000100B)也是 10003000
注意"File Type: DLL",这是根据PE的域来的。

编译并运行得到的输出是
cl main.c module.lib && main.exe
10003000
10001000: A1 00 30 00 10 C3 8B 44 24 04 A3 00
10001006: 8B 44 24 04 A3 00 30 00 10 C3 00 00

error_code的地址和指令中使用的地址是相同的。


3. dll relocation

上面 module.dll 恰好加载在首选基地址,所以没有发生重定项。
要演示重定项发生的情况, 可以将 module.dll 复制一份, 然后用 LoadLibrary 加载。
或者直接首选基地址为一个会冲突的, exe的默认基地址0x400000。

cl /LD /O1 module.c /link /noentry /base:0x400000

dumpbin /all module.dll | find /i "image base"
400000 image base (00400000 to 00404FFF)

dumpbin /disasm /relocations module.dll
00401000: A1 00 30 40 00 mov eax,dword ptr ds:[00403000h]
00401005: C3 ret
00401006: 8B 44 24 04 mov eax,dword ptr [esp+4]
0040100A: A3 00 30 40 00 mov dword ptr ds:[00403000h],eax
0040100F: C3 ret

BASE RELOCATIONS #4
1000 RVA, C SizeOfBlock
1 HIGHLOW 00403000
B HIGHLOW 00403000

cl main.c module.lib && main.exe
00393000
00391000: A1 00 30 39 00 C3 8B 44 24 04 A3 00
00391006: 8B 44 24 04 A3 00 30 39 00 C3 00 00

对比 dumpbin 得到的反汇编与 main.exe 的输出,可以发现指令中的操作数有相应的修改,以正确的使用00393000上的变量error_code。


4. dll fixed

如果链接时选择基地址固定
cl /LD /O1 module.c /link /noentry /base:0x400000 /fixed

产生的dll里就没有重定项信息
dumpbin /relocations module.dll

并且选择的是一个肯定会冲突的基地址,所以加载main.exe就会失败。

main.exe


5. exe export

默认exe是不会包含重定项信息的
cl /O1 module.c && dumpbin /relocations module.exe

File Type: EXECUTABLE IMAGE

注意"File Type: EXECUTABLE IMAGE",这是根据PE的域来的。

并且首选基地址也是冲突的。
dumpbin /all module.exe | find /i "image base"
400000 image base (00400000 to 0040BFFF)

但是让 main.c 链接到 module.exe 可以运行成功(之前dll fixed的情况是加载 main.exe 失败)
cl main.c module.lib & main.exe
0039B700
00391000: A1 00 B7 40 00 C3 8B 44 24 04 A3 00
00391006: 8B 44 24 04 A3 00 B7 40 00 C3 33 C0

注意指令里的操作码,并没有修改为error_code的地址:0039B700。
如果真的调用了get和set,也只是读写了其他的地址,而不是error_code。
bug已经产生了。 没崩只是运气, 那个地址恰好有读写权限。
而且实验代码一般都比较短,跑完马上就退出了,这种意外的写入产生的影响也不一定能发现。

6. exe export with relocation information

可以用 /fixed:no 附带上重定项信息
cl /O1 module.c /link /fixed:no

dumpbin /relocations module.exe 会产生很多输出,因为它还引用了libc。

而让 main.c 链接到 module.exe 并运行的同样不会发生重定项
cl main.c module.lib & main.exe
0039B700
00391000: A1 00 B7 40 00 C3 8B 44 24 04 A3 00
00391006: 8B 44 24 04 A3 00 B7 40 00 C3 33 C0
re: EXE导出函数 OwnWaterloo 2012-12-04 15:12
@zuhd
没有崩溃=没有问题=程序正确?

*(int*)随便写个什么地址 = 12; // 只要运气好,同样不会立即崩溃。
re: EXE导出函数 OwnWaterloo 2012-12-02 16:50
@溪流
另外,load是不会根据dll/exe后缀名来判断是否是dll还是exe。
它是根据pe格式中的一个域来判断的。具体位置我忘了。。。不过dumpbin好像能显示出来。

也就是说。。。很多那些后缀是exe(甚至是ocx什么的),而且加载后也能成功调用里面函数的文件,其实按pe格式来说都是dll文件,只是后缀名没有用dll而已。
re: EXE导出函数 OwnWaterloo 2012-12-02 16:48
@溪流
两个都是dllexport。两个函数产生的代码都会用上error_code的地址。

链接产生这个dll/exe的时候,是很难确切地知道加载后该dll/exe的地址。同样也很难确切知道error_code的地址,因为它和dll/exe被加载后的基地址之间的偏移是链接后就固定了的。

于是链接器只能先假设dll/exe会被加载到某个位置(首选基地址),然后根据它产生代码。

比如一种极端情况,将dll/exe复制一份本地文件(首选基地址相同),然后loadlibrary它俩。
那么,至少有一个dll/exe是无法被加载到首选基地址的,也就是set/get的指令中使用的地址是不正确的。

如果是dll,没有被加载到首选基地址的话,就会发生重定项。set/get的指令会相应的修改。
而exe,我记得loader就不会做这个工作,于是就。。。
re: EXE导出函数 OwnWaterloo 2012-12-02 16:36
@溪流
手误。。。我的错。。。
re: EXE导出函数 OwnWaterloo 2012-12-01 13:15
exe和dll还是有很多区别的。
首先entrypoint肯定就被忽略了。
其次重定位和依赖加载好像也会有问题。

比如试试这个?
int error_code;
__declspec(dllexport) int get_error(void) { return error_code; }
__declspec(dllimport) void set_error(int x) { error_code = x; }

get和set产生的指令里会有error_code的地址。
如果是dll,加载时指令中的地址会被正确地重定位。
而exe不行,即使保留重定位信息也不行。

exe可以被加载应该是为了里面的资源而不是代码。
re: 裸写一个含内嵌IE控件的窗口 OwnWaterloo 2012-09-02 20:50
@溪流
嗯,如果表达式的值被设计为没有意义的话,就可以(void),避免被使用。
re: 裸写一个含内嵌IE控件的窗口 OwnWaterloo 2012-09-02 19:58
@溪流
不一定是不care,有可能是不能胜任。虽然结果都一样,但不能与不愿的原因可是有区别的。

OO确实更简单、更natural,对看不出person.learn(language)与learn(person, language) 是一回事的人来说的话。
re: 裸写一个含内嵌IE控件的窗口 OwnWaterloo 2012-09-02 19:50
@溪流
1, 2, 3逗号运算符,最后转型为void。

从后面的例子来看。。。 可能是为了让那一整托东西是一个表达式。
你试试实现assert就能体会了。。。
re: 裸写一个含内嵌IE控件的窗口 OwnWaterloo 2012-09-02 12:07
@溪流
至于躲开的技巧。。。 其实事情起因是这样。。。
大概08-10年我就在cppblog或者CU(不记得是哪个地方了,又或者都有说)上说interface存在的问题。


一个函数f,它对它的参数有一些要求,例如你的代码中不是E_NOTIMPL那些。 而不同的函数对它的参数有不同的需求。

但interface的问题就是,它不能直接描述某函数Fi的需求, 它一定需要一个 **打包** 的过程。

那这个打包的粒度是否恰当,以相信interface是解决问题的方案的人自身的说法, 就看 *设计师(架构师)* 的本事了。
他们还会传授一些经验技巧, 比如"每个interface包含3-5个method比较合适"什么的, 笑死人了。


以我这种不相信interface是解决问题的方案的人来看, 那些展现漂亮的设计的demonstration,也只能在demonstration里维持它的漂亮。
随着系统滚大, interface就不能恰如其分的描述出需求。

例如, 就会出现某个函数Fi, 它接受到某个interface Ij, 但它需要interface Ik, 于是就只能 *运行时查询* , 丢失了静态类型检测。

不是 *架构师* 的设计失误, 而是他要在 *让每个interface Ij都能尽量恰到好处的描述出它使用者Fk 的需求* 与 *让总的interface数目维持在一个可接受的范围内* 之间作一个 *权衡* 。

对实际稍微大一些的系统, 如果想让demonstration展示出的漂亮设计延续下去, 需要的interface数目就会超出人的接受能力。demonstration演示不出这一点。

这是interface本身的缺陷 —— 需要将一组需求打包(还有其他很多, 先不说了。。。)。 架构师只能缓解, 没法解决。



对E_NOTIMPL,其实在C++里还好。。。 因为C++支持多继承。。。
让父类提供默认实现, 子类只override需要的便是。。。 而Java那种单继承就完蛋了。
只是不知道为什么IOleXXX没有这样设计。

对那种需要动态查询,从interface Ij转换到Ik的情况,QueryInterface什么的,真是无能为力。。。



反观duck typing —— 记得你也用Python的吧 —— 就没有这样的限制。
只要实现一个class, 让它支持那些不是返回E_NOTIMPL的method就完了。
甚至都不需要IOleXXX或者QueryInterface这些概念。
每个函数Fi对它的参数们的要求虽然是 *隐式的*, 但却是 *精确的*, 不多不少。

脱离Python,更一般的情况来说,要达到"Fi对它的参数的要求*不多不少*, 参数能 *恰如其分* 的实现这些要求"的目标, 并不一定需要 *隐式*, 也不一定需要Python那样的动态类型。
可以是显式的、 静态类型的, 例如Haskell。

使用interface的语言里,一个类型要实现什么interface在类型定义的时候就必须决定, 是另一个设计缺陷。 至少在C++/Java/C#里是这样。
至于其他的静态类型的OO语言。。。我学语言有个标准。。。 就是如果这语言强调自己是支持OO的, 那就不学。 所以其他静态类型的OO语言也不知道。


扯了一大通。。。 其实是想说。。。
我以前只是 *预感* interface的设计在稍微大一点的系统里就会出问题。
但对使用interface的大的系统都没有研究的兴趣。。。 看着头就痛。。。 因此说明这问题的 *实际例子* 比较匮乏。。。
于是看到你的文章就有兴趣了。。。 "看吧,我果然是对的!" <- 心声大致是这样。
re: 裸写一个含内嵌IE控件的窗口 OwnWaterloo 2012-09-02 11:37
@溪流
>> 不知道转载了,搜一下先^_^~
我是订阅了cppblog的所有文章、首页原创、还有有几爷子的单独的。。。
所以不用搜就知道这个事。。。
但最近这种同一文章在所有文章里出现4-5次,首页原创里出现4-5次,那几爷子的单独的rss里再出现4-5次。。。 吃不消啊。。。
re: 裸写一个含内嵌IE控件的窗口 OwnWaterloo 2012-09-01 21:22
啊,先跑个题。。。这文章是原创吧?有你的风格。。。
但你发现没有。。。这文章在cppblog里转载了好几个地方。。。
而且那几爷子的blog最近都这样,统一发同一篇文章。。。
之前还在想是不是有个是主号、其他是马甲。。。 看来全都是马甲吗。。。


嗯,我关注的是这里: >> 这三个接口,连带他们的父类,总共需要实现31个接口!不过还好,除了篇幅稍微长一点,基本上都是E_NOTIMPL。
想了解这种情况会不会经常发生?

就是说,父类定义了N个虚函数(是纯虚吗?其实是不是都无所谓)。子类override之,然后传递一个子类到某个地方。但其实传递进去的子类,它们的那N个虚函数中只有少部分被调用。

于是只能E_NOTIMPL啥啥的。。。
@西月弦
Haskell我也是新手,感觉收获最大的是 http://learnyouahaskell.com/
其次是 http://www.haskell.org/tutorial/ 内容不多,但信息量很大……
real world haskell对语言的介绍根本不够看懂它里面提供的代码……

函数式编程没专门看过什么数据……

PS:cppblog的通知邮件被gmail当作垃圾了……
lastButOne xs = case xs of { [] -> Nothing ; y:[] -> Nothing ; x:y:[] -> Just x ; x:xs -> lastButOne xs}

或者:
lastButOne [] = Nothing
lastButOne y:[] = Nothing
lastButOne x:y:[] = Just x
lastButOne x:xs = lastButOne xs


《real world haskell》不怎么讲语言的……
re: 傻瓜学习C语言进制转换 OwnWaterloo 2011-12-27 02:21
炮姐好……
@UGP
joel这篇文章足以暴露他思维层次太低。


即使是在C语言中,对i+j,同样不能确定它究竟做了什么。
完全被优化掉了?
还是上下文中有重复计算,此处直接取的结果?
但有多少人是真正关心i+j具体被如何处理,实现的么?
绝大多数情况都不需要。

那为什么对C++,就要求了解i+j是具体在干什么呢?
做出这样批评的人,都是 *只懂得C级别的抽象方式,不懂得C++级别的抽象方式* 而已。


对异常也是如此。
对自己熟悉的方式根深蒂固,以至于根本就无法恰当分析其他方式。
他的批评,比如让代码难以理解,熟悉异常的人的眼中完全不可理解。


而匈牙利更是扇自己嘴巴。
他要的就是将safe与unsafe字符串通过某种方式告诉编译器。
比如用不同类型,限制它们之间的自由转换,转换只能通过可控制的有限方式。
然后,让 *编译器自动地完成这样的检测* ,而不是什么手工肉眼去比。
@stepinto
上面有条回复正中要害:
>> 结论:google禁止异常比较省钱。

那么,你们禁止使用(了解)异常(以及其他各种技术)是为了什么呢?
为了当你所说的那种
>> 水平并不那么出色的开发者
对吗? 你就甘愿当这种拖后腿的人,是吗?

>> 可以看一下exceptional C++的第二章,然后再来这里发言吧。
不好意思,整个exceptional系列我都看过好多年了。
你想得到的与想不到的C++书籍我都看过。
你想得到的与想不到的C++技术我都玩过。
所以我才看不起你们这种 *为自己的无能找借口* 的人。
@溪流
另一种方式: 将那些退出测试点, 换成设置一个完成标记。

退出测试:
发出的中止请求会"延迟"到执行退出测试点时。
这个退出点之前的工作都是完成的, 余下的是放弃的。

完成标记:
发出的中止请求会"立即" —— 可能也会有一些延迟, 但至少不会等待到下一个完成标记 —— 执行。
上一个完成标记前的工作是完成的, 余下的是放弃的。

就看你的工作是否能分开了……
比如, 数据如果是行为单位, 就可以写一行后增加行计数。
行计数前的数据是有效的。
如果数据是, 比如xml, 那就完蛋……

@杨粼波
lz需要的应该是"被其他线程中止", 而不是"自主中止" —— 否则直接return不就完了?
coroutine 是自主切换的, COoperate。
@溪流
哦, 你还想要 "安全的退出点" 啊?
你想想这两种需求是否是矛盾的……
1. 只在一些点上可退出
2. 代码中在这些点上又不要显式写出测试
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

DWORD CALLBACK infinite(void* arg) { for (;;) Sleep(0); return 0; }
void cancel(void) { ExitThread(12); }

int main(void)
{

DWORD tid = 0;
HANDLE thread = CreateThread(NULL, 0, infinite, 0, 0, &tid);
CONTEXT ctx = {0};
ctx.ContextFlags = CONTEXT_ALL;
SuspendThread(thread);
GetThreadContext(thread, &ctx);
ctx.Eip = (DWORD)cancel;
SetThreadContext(thread, &ctx);
ResumeThread(thread);
WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(thread, &tid);
CloseHandle(thread);
return (int)tid;

}
SetThreadContext/GetThreadContext?
在其他线程上执行 setjmp/longjmp... 太有意思了……
setjmp 到 longjmp 之间的C++代码全得重写…… 哇……
@溪流
恩, 我还觉得 loki.scopeguard应该区分为
1. rollback 注册的动作可取消 —— loki.scopeguard实际实现
2. on_exit 注册的动作一定执行 —— 其实这个用得不少

将 loki.scopeguard 用于 on_exit 的情况很浪费啊……
需要开辟局部变量, 需要 if 测试, 而且这个测试代码是在每一个退出点产生的……
这些开销根本不需要的。

loki应该是为了简单吧, 一顶俩……
rollback函数本身就不应该抛出异常。
异常安全的代码依赖一些无抛出的代码来执行commit或者rollback。

所以:
1. 本来面目是还不了的
rollback动作就应该无抛出的执行, 无论它本身是一个无抛出的函数, 还是被scopeguard的析构所吞掉。

2. scopeguard是否应该插手
我也认为它多管闲事了。
无抛出是rollback函数自身的责任。
没有无抛出保证就不能称为一个rollback。
应该努力将其写为rollback, 然后scopeguard仅仅考虑注册而已。
对实在没有时间与精力写为无抛出的rollback, 可自行吞掉:
rollback_nothrow(...) { rollback(...) }
makeguard(rollback_nothrow, ...)

3. loki
loki应该算是一个实验/教学性质的库吧?
所以尽可能的多传授一些C++的知识, 比如"析构绝对不能抛出异常"。
而没太注重"该保证是谁的责任"。
所以就选择一个简单且效率稍微有点低的方案了。
re: Lisp一瞥:增强型变量Symbol OwnWaterloo 2011-03-22 12:10
用C++去对比lisp, 当然会走弯路……
re: 学习下 WTL 的 thunk OwnWaterloo 2011-03-17 23:24
@溪流
嘿, 多谢理解~
@陈梓瀚(vczh)
vc6确实对C++确实有点过分了。
那改成如果发布C++, 用VC8的sln, VC9,10都可以编译。
如果发布C, 那用VC6的dsw, VC6,8,9,10都可以编译。
@陈梓瀚(vczh)
硬件当然再进步, 可以换更快的。
但这和更新软件是两码事。

有更快的硬件, 不是"我们就应该用更消耗硬件资源软件"的理由吧?
@溪流
对于编辑C/C++来说, 除了慢, 没发现08比05有什么新功能……
对于发布来说, 发布一个VC6的dsw, 用户只要不低于VC6, 他就能编译。
高版本的IDE有从低版本工程文件导入的功能, 反之没有……
@溪流
在足够牛b的机器上 eclipse netbeans也不慢, 你用吗~
@陈梓瀚(vczh)
貌似08和05的sln格式区别就只有第1行?

其实我是觉得08很慢, 比05慢。
据用过10同学说, 10更慢……
如果公司要强制推行自家的新产品就有点过分了……

如果只是开发C/C++, 不涉及.net和html什么的, 08、10完全没优势?
如果要用C++0x, 可以用单独的cl16, IDE还是用05……
我就只下了cl16, 没有VS10的IDE……
@空明流转
gdb不一定有这个功能, 而且也不应该有这个功能吧?
从VC6不支持来看, 也应该是IDE实现的而不是windbg。

只要有耐心, emacs应该是可以实现的。
@陈梓瀚(vczh)
这人的名字真诡异……
BTW, 微软内部使用VS是怎么算的? 也需要"购买"什么的么?
会被强制使用最新版本么? 2010?
学习鸟!!!
re: 2009-2010小结(五)离职始末 OwnWaterloo 2011-01-27 19:30
@溪流
>> 像是……带版本控制的wiki?
嗯, 不过自动化程度不如wiki……
但使用的标记语言不受限制, 总之最后能产生html就行了。
re: 2009-2010小结(五)离职始末 OwnWaterloo 2011-01-27 16:58
@陈梓瀚(vczh)
忍不住, 手会痒……
re: 2009-2010小结(五)离职始末 OwnWaterloo 2011-01-27 14:18
@陈梓瀚(vczh)
msn的writer? live writer? 微软那个?
试过一小会…… 貌似也是用metablog api来发表post。

而且不习惯富文本编辑…… 可能代码写惯了……
纯文本, 可以啪啪啪啪胡乱写一堆, 把脑袋里的东西先倒出来, 再慢慢整理。
而富文本, 总是忍不住一边编辑, 一边就去调整格式了……
纯文本感觉对编程也友好一些, 如果原始标记不够用, 可自己添加个预处理什么的; 而二进制格式文档如果功能不够用, 就只好干瞪眼了……
re: 2009-2010小结(五)离职始末 OwnWaterloo 2011-01-26 23:39
当中还想过其他比较取巧的办法……

比如, 看这个: http://simplejson.googlecode.com/svn/tags/simplejson-2.0.9/docs/index.html

这个是产生文档的source:
http://simplejson.googlecode.com/svn/tags/simplejson-2.0.9/docs/_sources/index.txt

语法是上面提到的rst, 用的sphinx。


将blog当作一个project:
1. 纯文本编写
2. 可diff
3. 版本控制之下
4. 评论什么的, project会提供code review, issue track, rss, email notify等功能

够sexy吧?


但最终还是觉得会比较受限……
自己弄一个, 还可以顺带当作练习……
反正也不急…… 慢慢弄……
re: 2009-2010小结(五)离职始末 OwnWaterloo 2011-01-26 23:31
看来得解释一下……
我是有写的, 还不少, 相当的多, 估计有4位数左右了。
只是没发而已……


没发的原因是感觉cppblog不够给力……
其实, 相比我写文章的方式, emacs+rst ,我试过的所有blog的在线编辑器都不够给力……
如果真用blog的editor, 也肯定写不了那么多, 思路会被扰乱的……


也想过用metablog api, 将线下的文档发上来; 但估计格式什么的还是会不满意。
所以我想自己搭一个blog, 而不是用现有的blog服务, 那样的话, 可控制的范围要大得多, 可以较少的受制于人……


我已经在动手了…… 去年圣诞节申请了gae。
但我对网络方面的东西一窍不通…… 冬天手也动坏了…… 敲键盘比较痛……
再加上各种乱七八糟的事……
估计要折腾相当长一阵子……


现在想法是先作为一个放文档, 并有永久链接的地方。
索引、 评论、rss、 代码高亮、 这些功能慢慢加……
似乎就这些功能比较重要?


也不想用Django或者micolog这样的东西, 不然早就投奔wordpress什么的去了……
就是希望借这个机会(上面说了, 这方面能力几乎为零), 自己动手从零开始构建, 嗯, 造个轮子……
反正是我自己用, 造成方的也不会害到其他人……


嗯, 就是这样……
@yrj
>> 我想要知道的是每种方法的优缺点和它的适用条件,应用时根据不同的需求选择适合的方法。

嗯, 这是王道。
根据问题选合适的方案, 而不是将自己熟悉的方案去套各种问题。

关键是, 孟岩只提一方面(灵活性) 不提其代价。 片面的给C++抹黑。
仿佛能给C++抹黑就显得自己多高水平似的。
@yrj
孟岩的是吧?
当时这篇文章在buzz上被分享是我就不予好评。
理由就是上面和cexer提到的, 完全的动态, 纯面向对象而不是面向class是有代价的, 而且是C++必定不能承受的代价。
只知道说C++这不好, 那不好, 也不想想为什么。
他的文章(至少C++相关那些)在我看来都是水多料少。
也许时代不同了吧……
@溪流
template <typename S>
class C;

template <typename R>
class C<R (__stdcall*)()> {};

template <typename R>
class C<R (__stdcall&)()> {};

"函数类型"是一个很灰色的地带……
就批量下载图片这个case来说, C++能提高什么效率?
网络传输才是大头, 这C++是提升不了的。
也就提高解析html的效率…… 但那是多么蛋疼的事情……

5秒传输是死的。
0.5秒python解析, 与0秒(算极端情况)C++解析
体会不到差异……
@溪流
举个例子嘛……

不行就再举个, 比如登录, 批量下载图片……
嗯, 就是校内…… 我就是因为这个学python的。

最开始是打算用 libcurl, 但发现C/C++处理字符串太蛋疼……
又打算将 libcurl绑定到lua, 算练手(因为那时候python还不熟)
最终发现还是麻烦, 直接用python了……

嗯, wget 什么的我不熟……
用python做也算顺便练习吧……
@溪流
嗯, 这是一个绕开的方法, 然后通过别的机制去获得F的返回类型与参数列表还有调用约定。

在我的那个case里, 返回类型、参数列表、调用约定都要获取, 并对不同的调用约定做不同的事。
嗯, 就是thunk啦, 你懂的。

最终还是要获取那些信息, 所以我直接用
template<R>
R call ( R (*f) )
来获取了。 这机制叫啥名一下子想不起来了……


但这对g++依然不行。
产生的两个函数相互依然是重定义。
@溪流
误会误会…… 我说的"日常"是指工作饭碗以外的……

比如, 用metablog 转移blog文章, 好像就是你写过的吧?
这用C/C++就蛋疼了……

就是一些个人事务, 有重复与机械的味道, 而用C/C++去做太麻烦。
共10页: 1 2 3 4 5 6 7 8 9 Last 
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(8)

随笔档案(16)

链接

搜索

  •  

积分与排名

  • 积分 - 196968
  • 排名 - 132

最新随笔

最新评论

阅读排行榜

评论排行榜