gpt4 book ai didi

mysql - VC++ 将数组^存储在MySql数据库中

转载 作者:行者123 更新时间:2023-11-29 19:29:41 24 4
gpt4 key购买 nike

我正在开发 VC++ cli 应用程序,我需要将图像存储到 MySql 数据库中。我意识到这通常不是一个好的做法,但由于对文件系统的访问有限,这是我必须采取的方式。

因此,我已经能够将图像放入托管的无符号字符数组中,这看起来就像我在网上找到的示例中必须执行的操作(这些示例主要是 C# 语言,并且包含不可用的命令)。我只需要弄清楚如何将其存入数据库,我很茫然,而且我的搜索至少没有发现任何对 VC++ 有用的东西。

这是我需要做的,我有一个托管数组:

array<unsigned char>^ imageSource;

通过使用包含图像的字节:

System::IO::FileStream^ fs;
System::IO::BinaryReader^ br;

//Read the Image
fs = gcnew System::IO::FileStream(filepath, System::IO::FileMode::Open, System::IO::FileAccess::Read);
br = gcnew System::IO::BinaryReader(fs);

//Store the Image into an array
imageSource = br->ReadBytes((int)fs->Length);

接下来我需要将其保存到我的数据库中:

sql::Connection *sqlConn;
sql::PreparedStatement *sqlStmt;
sql::ResultSet *sqlResult;

// Sql Connection Code

//I have a Routine to save images
//and have Select because get_last_insert_id() is not available in the c++ connector
sqlStr = "SELECT save_item_image (?, ?, ?, ?, ?) AS ID";

//Prepare the Query
sqlStmt = this->sqlConn->prepareStatement(sqlStr);

//Set Parameters in SqlStatment
sqlStmt->setInt(1, 1);
sqlStmt->setInt(2, 1);
sqlStmt->setBlob(3, &imgSource); <-- This is where I need to insert image
sqlStmt->setString(4, "jpg");
sqlStmt->setString(5, "test.jpg");
sqlStmt->executeUpdate();

据我了解,setBlob 函数需要 std::istream 来读取数据。我不知道如何解决这个问题,这是我遇到的主要问题。

最佳答案

我终于弄清楚了这一点,并想发布一个答案,以防其他人正在寻找这个问题的答案。

实现此目的的最简单方法是使用 pin_ptr 引用托管数组中的第一个元素,该元素实际上是指向整个数组的指针。接下来我们转换为另一个指针,最后转换为 char* 指针。最后,为了在 setBlob 中使用它,我们需要为 istream 创建一个内存缓冲区。

这是一个工作示例:

将图像文件读取到托管数组:

array<unsigned char>^ rawImageData;
System::IO::FileStream^ fs;
System::IO::BinaryReader^ br;

//Setup the filestream and binary reader
fs = gcnew System::IO::FileStream(filepath, System::IO::FileMode::Open, System::IO::FileAccess::Read);
br = gcnew System::IO::BinaryReader(fs);

//Store the Image into a byte array
rawImageData = br->ReadBytes((int)fs->Length);

内存缓冲区

#include <iostream>
#include <istream>
#include <streambuf>
#include <string>

struct membuf : std::streambuf {
membuf(char* begin, char* end) {
this->setg(begin, begin, end);
}
};

最后是 MySQL 代码:

sql::Driver *sqlDriver;             
sql::Connection *sqlConn;
sql::PreparedStatement *sqlStmt;
sql::ResultSet *sqlResult;

/*** SQL Connection Code Here ***/

//Build the Item Sql String to Save Images
sqlStr = "SELECT save_item_image (?, ?, ?, ?, ?) AS ID";

//Prepare the Query
sqlStmt = sqlConn->prepareStatement(sqlStr);

//Create a pin_ptr to the first element in the managed array
pin_ptr<unsigned char> p = &rawImageData[0];

//Get a char pointer to use in the memory buffer
unsigned char* pby = p;
char* pch = reinterpret_cast<char*>(pby);

//Memory Buffer, note the use of length from the RawImageData, images contain
//NULL char's so size_of doesn't return the right length.
membuf sbuf(pch, pch + rawImageData->Length);

//Create the istream to use in the setBlob
std::istream sb(&sbuf, std::ios::binary | std::ios::out);

//Finally save everything into the database
sqlStmt->setInt(1, 1);
sqlStmt->setInt(2, 1);
sqlStmt->setBlob(3, &sb); //*** Insert the Image ***/
sqlStmt->setString(4, "Name");
sqlStmt->setString(5, "Path");
sqlStmt->executeUpdate();

sqlResult = sqlStmt->getResultSet();

//Make sure everything was executed ok
if (sqlResult->rowsCount() > 0) {
sqlResult->next();
int image_id = sqlResult->getInt("ID");
}

注意:我在 sql 字符串中使用了 SELECT,因为 save_item_image 实际上是一个返回插入图像 id 的函数。我需要使用此方法,因为没有其他方法可以获取最后在 C++ 连接器中插入的 ID(我可以找到)。在其他 MySql 库中,有一个 last_insert_id() 命令,但在连接器中没有。

关于mysql - VC++ 将数组<unsigned char>^存储在MySql数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41883266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com