Marmalade Core Storage (s3eSecureStoragePut & s3eSecureStorageGet) not persisting
Marmalade Core Storage (s3eSecureStoragePut & s3eSecureStorageGet) not persisting
我有一个使用Marmalade Core制作的最小应用程序。它创建一个web视图,然后使用s3eSecureStoragePut&s3eSecureStorageGet。
在我关闭应用程序并重新打开它之前,这一切都很好。在它再次加载并尝试加载数据后,它返回为空。有人知道为什么会发生这种事吗?它是使用GCC ARM Debug为Android 构建/部署的
这是我的c++
#include "s3e.h"
#include "s3eDevice.h"
#include "IwDebug.h"
#include "s3eWebView.h"
#include "IwGx.h"
#include "Iw2D.h"
#include <string>
#include <sstream>
s3eWebView* webView;
bool pageLoaded;
const char* rom = "rom://index.html";
struct SStoreData {
std::string key;
};
static int loadedCallback(s3eWebView* instance, void* sysData, void* userData) {
pageLoaded = true;
return 1;
}
static int javaScriptCallback(s3eWebView* instance, void* systemData, void* userData) {
//cast the data to string for easier handling
std::string data = (char*) systemData;
char jsFunc[128];
//check if page has loaded to prevent errors
if (pageLoaded) {
if (!std::strncmp(data.c_str(), "saveKey", std::strlen("saveKey"))) {
std::string key = data.substr(data.find("|") + 1, data.length());
SStoreData *toSave = new SStoreData;
toSave->key = key;
s3eSecureStoragePut (toSave, sizeof (*toSave));
} else if ("loadKey" == data) {
SStoreData *toLoad = new SStoreData;
s3eSecureStorageGet (toLoad,sizeof(*toLoad));
sprintf(jsFunc, "dataLoaded("%s", "key");", toLoad->key.c_str());
s3eWebViewSendJavaScript(webView, jsFunc);
} else {
IwTrace(JS_CALLBACK, ("DID NOT RECEIVE ANYTHING"));
}
}
return 1;
}
void init() {
//init vars
webView = s3eWebViewCreate(false);
pageLoaded = false;
//register callbacks
s3eWebViewRegister(S3E_WEBVIEW_FINISHED_LOADING, loadedCallback, NULL, webView);
s3eWebViewRegister(S3E_WEBVIEW_FROM_JAVASCRIPT, javaScriptCallback, NULL, webView);
//navigate to the webpage
s3eWebViewNavigate(webView, rom);
//display the webview
s3eWebViewShow(webView, 0, 0, IwGxGetDisplayWidth(), IwGxGetDisplayHeight());
}
void destroy() {
if (webView) {
s3eWebViewDestroy(webView);
webView = NULL;
//unregister callbacks
s3eWebViewUnRegister(S3E_WEBVIEW_FINISHED_LOADING, loadedCallback, webView);
s3eWebViewUnRegister(S3E_WEBVIEW_FROM_JAVASCRIPT, javaScriptCallback, webView);
}
delete rom;
//gives me warning so I'm leaving it out.
//delete pipHandler;
}
// Main entry point for the application
int main()
{
//Initialise graphics system(s)
//Initialise graphics system(s)
Iw2DInit();
//Init
init();
// Loop forever, until the user or the OS performs some action to quit the app
while (!s3eDeviceCheckQuitRequest()) {
//Update the input systems
s3eKeyboardUpdate();
s3ePointerUpdate();
// Your rendering/app code goes here.
// Sleep for 0ms to allow the OS to process events etc.
s3eDeviceYield(0);
}
destroy();
//Terminate modules being used
// Return
return 0;
}
这是webview 的html/js
<!DOCTYPE html>
<html>
<head>
<title>Storage Spike</title>
</head>
<body onload="main();">
<div>Loaded value:<span id="loadedKey">(loaded value goes here)</span></div>
<input type="text" id="inputKey" value="123key" placeholder="enter key to save"/>
<button id="saveKey">Save</button>
<button id="loadKey">Load</button>
<br>
<script>
function main()
{
var saveKey = document.getElementById("saveKey");
var loadKey = document.getElementById("loadKey");
var inputKey = document.getElementById("inputKey");
saveKey.addEventListener("click", function() {
var key = inputKey.value;
s3e.exec("saveKey|" + key);
});
loadKey.addEventListener("click", function() {
s3e.exec("loadKey");
});
}
function dataLoaded(data, type)
{
console.log(data);
console.log(type);
var loadedKey = document.getElementById("loadedKey");
if(type === "key")
loadedKey.innerHTML = data;
else
console.log("type error");
}
</script>
</body>
</html>
任何帮助都将不胜感激,
亲切问候
问题是您试图直接保存std::string的实例。
std::string实例只不过是三个指针,用于描述用于存储实际字符串数据的内存。当应用程序关闭或用于存储数据的内存释放时,这些指针将失去所有意义。
您需要将实际的字符串数据保存到s3eSecureStorage中,以使其持久化。为此,您需要序列化std::string实例。进行序列化的一种简单方法是首先保存字符串的长度,然后保存实际的字符串数据。
要序列化字符串并将其保存到s3eSecureStorage,可以执行以下操作:
std::string input = "exampledata";
uint16 inputSize = static_cast<uint16>(input.size());
uint16 bufferSize = static_cast<uint16>(sizeof(uint16) + inputSize);
buffer = new char[bufferSize];
std::memcpy(buffer, &inputSize, sizeof(uint16));
std::memcpy(buffer + sizeof(uint16), input.c_str(), inputSize);
s3eSecureStoragePut(buffer, bufferSize);
delete[] buffer;
要从s3eSecureStorage获取数据并反序列化字符串,可以执行以下操作:
std::string output;
uint16 dataSize = 0;
s3eSecureStorageGet(&dataSize, sizeof(uint16));
if (dataSize > 0) {
uint16 bufferSize = static_cast<uint16>(dataSize + sizeof(uint16));
char* buffer = new char[bufferSize];
s3eSecureStorageGet(buffer, bufferSize);
output.resize(dataSize);
std::memcpy(&output[0], buffer + sizeof(uint16), dataSize);
delete[] buffer;
}
如果要存储多个值,序列化需要稍微复杂一些,但基本思想是一样的。
显然,当没有任何内容保存到s3eSecureStorage时,您还需要使用某种错误处理。
您发布的代码在应用程序的一次执行中起作用的原因是,您为SStoreData实例分配了new,但从未发布过它。当您从s3eSecureStorage加载回指针时,它们仍然指向保存字符串数据的已分配内存。
相关文章:
- 没有找到相关文章