我正在开发 MariaDB 连接器 C 的包装器。有一种典型情况是开发人员不知道存储在字段中的数据的长度。正如我所知道的,获得字段实际长度的方法之一是将长度缓冲区传递给mysql_stmt_bind_result,然后通过调用mysql_stmt_fetch_column来获取每一列。但我无法理解函数mysql_stmt_fetch_column是如何工作的,因为我遇到了内存损坏和应用程序中止。
这是我努力实现目标的方式
// preparations here
...
if (!mysql_stmt_execute(stmt))
{
int columnNum = mysql_stmt_field_count(stmt);
if (columnNum > 0)
{
MYSQL_RES* metadata = mysql_stmt_result_metadata(stmt);
MYSQL_FIELD* fields = mysql_fetch_fields(metadata);
MYSQL_BIND* result = new MYSQL_BIND[columnNum];
std::memset(result, 0, sizeof (MYSQL_BIND) * columnNum);
std::vector<unsigned long> lengths;
lengths.resize(columnNum);
for (int i = 0; i < columnNum; ++i)
result[i].length = &lengths[i];
if (!mysql_stmt_bind_result(stmt, result))
{
while (true)
{
int status = mysql_stmt_fetch(stmt);
if (status == 1)
{
m_lastError = mysql_stmt_error(stmt);
isOK = false;
break;
}
else if (status == MYSQL_NO_DATA)
{
isOK = true;
break;
}
for (int i = 0; i < columnNum; ++i)
{
my_bool isNull = true;
if (lengths.at(i) > 0)
{
result[i].buffer_type = fields[i].type;
result[i].is_null = &isNull;
result[i].buffer = malloc(lengths.at(i));
result[i].buffer_length = lengths.at(i);
mysql_stmt_fetch_column(stmt, result, i, 0);
if (!isNull)
{
// here I'm trying to read a result and I'm getting a valid result only from the first column
}
}
}
}
}
}
如果我将一个数组放入mysql_stmt_fetch_column,那么我将获取唯一有效的第一个字段,所有其他字段都是垃圾。如果我将单个 MYSQL_BIND 结构放入此函数,那么我将在大约第 74 个字段上中止应用程序(有趣的是它始终是这个字段)。如果我使用另一个 MYSQL_BIND 数组,那么情况与第一种情况相同。
请帮助我了解如何正确使用它!谢谢