SQLite3 C++:检索 Blob

3

我有一个存储在sqlite3数据库中的.png图片,以BLOB形式存储。

我正在尝试通过C++接口检索原始数据,如下所示:

RawImageWrapper* obj = 0;
int rc = sqlite3_exec(db, action.c_str(), imageSelectCallback, obj, &errMsg);

当action是我的SQL语句(它返回正确的记录)时,RawImageWrapper看起来像这样

struct RawImageWrapper
{
    int callback(int argc, char **argv, char **azColName) {
        for (int i = 0; i < argc; i++) {
            if (strcmp(azColName[i], "Image") == 0) {
                buff = std::string(argv[i]);
                return 0;
            }
        }
        return 1;
    }

    std::string buff;
};

使用字符串来保存图像数据可能不是最好的选择,但我只是想要一个快速的对象来包装char[]。然而,当它尝试构造buff时,会出现访问冲突。

从我的数据库中检索此图像blob并将其加载到某个容器中的正确方法是什么?我计划在稍后的时间从原始数据重新组成图像。


2
两个 bug:std::string 的构造函数接受 const char* 作为参数,但是当遇到第一个 NUL 字符时就会停止。对于二进制数据来说,这可能会过早地终止字符串的读取,或者在读取时超出有效内存范围。如果不知道数据长度,就不能像这样读取二进制数据。 - IInspectable
我明白了,你知道除了字符串之外还有更好的对象可以用于这个目的吗? - Madden
1
std::string 并没有固有的问题(虽然 std::vector<unsigned char> 可以更好地传达其目的)。你真正的问题是,你无法访问数据的长度。无论你使用哪种容器,你都需要知道数据的长度。 - IInspectable
嗯,我得想办法从API中获取那个,谢谢你的帮助。 - Madden
你需要用游标替换sqlite3_exec() - CL.
1个回答

0

sqlite3 blob数据的问题在于,如果您不知道blob的大小,则无法从char*构造string或任何其他对象。因为blob数据可以有null值,当您生成string时,它会在获取到null后立即停止,忽略其余数据。

我知道两种解决此问题的方法:

  1. 在您的SELECT语句中添加一个额外的输出,形式为LENGTH(BLOB_COLUMN),它会给出以字节为单位的blob列的大小。
  2. 使用select hex(BLOB_COLUMN) from ...将blob列转换为十六进制值,现在您获得了一个普通的十六进制string,之后您必须将其转换为原始字节数组

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接