d的符星示例
//-- 结果应为f.i. "哈哈"
//-- sqlite3_column_text返回`C串`
printf("%s\n",sqlite3_column_text(res, i));
writeln(sqlite3_column_text(res, i));
writefln("%s",sqlite3_column_text(res, i));
writefln(std.conv.to!string(sqlite3_column_text(res, i)));
//-- 结果:
哈哈
55B504B3CE98
55B504B3CE98
哈哈
对char*,必须用std.conv.to!string(..)吗?"%s"的意思?
D中,char*与串不一样.要用std.conv.fromStringZ(可避免分配)转换符*至D串.
还有不分配内存的转换版本,注意注释:
// 函数源
import std.stdio : writeln, writefln;
import core.stdc.stdio : printf;
import core.stdc.string : strlen;
const(char)* sqlite3_column_text(void*, int iCol)
{
return "你好";
}
void main()
{
// printf是需要0终止串`(char*)`的`libc`函数
printf("%s\n", sqlite3_column_text(null, 0));
// writeln是d函数,期望(是符的不变切片)串,切片是`T*+长度`.
// 从sqlite中取串
const(char)* ret = sqlite3_column_text(null, 0);
// 决定长度,
size_t len = strlen(ret);
// 构建切片.
string str = cast(string) ret[0 .. len];
writeln(str);
writefln("%s", str);
}
你这里发布的代码是不安全代码的完美示例:
import std;
char *sqlite3_column_text() @system {
return cast(char *)"哈哈".ptr;
}
void main() {
printf("%s\n",sqlite3_column_text());
writeln(sqlite3_column_text());
writefln("%s",sqlite3_column_text());
writefln(std.conv.to!string(sqlite3_column_text()));
}
不安全代码很麻烦.小心使用:
char[] s1 = fromStringz(sqlite3_column_text());
writeln(s1); // 一切正常
char[] s2 = fromStringz(sqlite3_column_text()); // 其他一些sqlite3API调用
writeln(s1); // sqlite3搞砸了s1
这是释放后使用.D可用@safe加上-dip1000开关来检测:
@safe:
import std;
char *sqlite3_column_text() @system {
return cast(char *)"哈哈".ptr;
}
string trusted_sqlite3_column_text() @trusted {
return std.conv.to!string(sqlite3_column_text());
}//这里可分配.
void main() {
printf("%s\n",sqlite3_column_text()); // 不!
writeln(sqlite3_column_text()); // 不!
writefln("%s",sqlite3_column_text()); // 不!
writefln(std.conv.to!string(sqlite3_column_t));// 不!
writeln(trusted_sqlite3_column_text()); // 好!
}
也许用sqlite3_column_blob()和sqlite3_column_bytes()来按串提取列文本会更有效?
浙公网安备 33010602011771号