I have a question regarding the usage of SQLite with Unreal Engine 5.0.3 c++ for deployment on Microsoft HoloLens 2 as Universal Windows Platform (UWP) application.
I have an own written library integrated in my Unreal Project as Module, which is dependent on SQLite (https://www.sqlite.org/), which allow me besides some business logics to read and write data to and from an SQLite database. In my own written library, I’m using the SQLite functionality through including the <sqlite/sqlite3.h> Header. To resolve the dependency, I’m using the official SQLite Plugin from Epic Games, Inc.. Further, I have extensive own written Unit-Tests, to test the functionality of my own written library, which are succeeding when I run the tests through the “Session Frontend” in the Unreal-Editor on my Local Windows machine. The database can be created, written, readen without any problem, as expected.
The application can be builded and tested on my local machine, without problems. The application can be build for Microsoft Hololens 2, deployed and run.
However, when running the application and the library on Microsoft Hololens 2 and the application wants to simply create a table in my database, I am receiving an “disk I/O error” with extended error code 5642: SQLITE_IOERR_SEEK. If I’m looking to the file directory (LocalState directory in project specific Appdata), I see the created database with 0kb data volume.
If anyone can help me, I would be really delighted, as I’m stuck on this Bug since a few days. If further informations are usefull, please don't hesitate to ask!
+CapabilityList=internetClientServer
+CapabilityList=privateNetworkClientServer
+CapabilityList=internetClient
+CapabilityList=AllJoyn
+CapabilityList=codeGeneration
+DeviceCapabilityList=microphone
+DeviceCapabilityList=webcam
+DeviceCapabilityList=gazeInput
+DeviceCapabilityList=wiFiControl
+DeviceCapabilityList=proximity
+DeviceCapabilityList=location
+DeviceCapabilityList=Bluetooth
+UapCapabilityList=musicLibrary
+UapCapabilityList=picturesLibrary
+UapCapabilityList=videosLibrary
+UapCapabilityList=blockedChatMessages
+UapCapabilityList=chat
+UapCapabilityList=enterpriseAuthentication
+UapCapabilityList=objects3D
+UapCapabilityList=phoneCall
+UapCapabilityList=removableStorage
+UapCapabilityList=sharedUserCertificates
+UapCapabilityList=userAccountInformation
+UapCapabilityList=voipCall
+Uap2CapabilityList=spatialPerception
+UapCapabilityList=appointments
+Uap3CapabilityList=backgroundMediaPlayback
+UapCapabilityList=contacts
+Uap6CapabilityList=graphicsCapture
+IotCapabilityList=lowLevelDevices
+Uap6CapabilityList=offlineMapsManagement
+Uap2CapabilityList=phoneCallHistoryPublic
+Uap3CapabilityList=remoteSystem
+IotCapabilityList=systemManagement
+Uap4CapabilityList=userDataTasks
+Uap3CapabilityList=userNotificationListener
+DeviceCapabilityList=lowLevel
+DeviceCapabilityList=pointOfService
+RescapCapabilityList=developmentModeNetwork
ISSUE SOLVED!
The bug is located in the Read
function in the SQLiteEmbeddedPlatform.cpp
of the UE SQLiteCore Plugin
by calling the Seek() function in HoloLensPlatformFile.cpp
when building for Microsoft HoloLens platform
. Diving into the Seek()
function of the FileHandle
implementation for Microsoft HoloLens Platform
, the error occurs in the FileSeek()
function which calls the function SetFilePointerEx()
from the Windows SDK 10.0.18362.0
located at Windows Kits\10\Include\10.0.18362.0\um\fileapi.h
. For some unknown reason, the function returns false. The corresponding Seek() function in WindowsPlatformFile.cpp
for the Windows platform
does not check the return value and always returns true.
The issue could be solved through building the SQLite library from source by a custom integrated Unreal Plugin named SQLiteZ
. The source code for the SQLite library (sqlite3.h, sqlite3.c) is used from SQLite amalgamation.
To use the library in the UE Plugin, in the SQLiteZ.Build.cs
file, the appropriated preprocessor statements must be properly set to build the SQLite library for Unreal UWP
to use on Microsoft HoloLense 2
.
For detailed information, refer to the code block below of the SQLiteZ.Build.cs
.
using UnrealBuildTool;
public class SQLiteZ : ModuleRules
{
public SQLiteZ(ReadOnlyTargetRules Target)
: base(Target)
{
PublicIncludePaths.AddRange(
new string[] {
// ... add public include paths required here ...
});
PrivateIncludePaths.AddRange(
new string[] {
// ... add other private include paths required here ...
});
PublicDependencyModuleNames.AddRange(
new string[] {
"Core",
// ... add other public dependencies that you statically link with here ...
});
PrivateDependencyModuleNames.AddRange(
new string[] {
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
// ... add private dependencies that you statically link with here ...
});
DynamicallyLoadedModuleNames.AddRange(
new string[] {
// ... add any modules that your module loads dynamically here ...
});
PrivateDefinitions.Add("SQLITE_API=__declspec(dllexport)");
PrivateDefinitions.Add("SQLITE_HAVE_ISNAN=1");
// Enable FTS
PrivateDefinitions.Add("SQLITE_ENABLE_FTS4");
PrivateDefinitions.Add("SQLITE_ENABLE_FTS5");
// Enable Deserialization and RTree Subsystem
PrivateDefinitions.Add("SQLITE_ENABLE_DESERIALIZE");
PrivateDefinitions.Add("SQLITE_ENABLE_RTREE");
// Enable Json extension
PrivateDefinitions.Add("SQLITE_ENABLE_JSON1");
if (Target.Platform == UnrealTargetPlatform.HoloLens) {
PrivateDefinitions.Add("SQLITE_OS_WINRT=1");
}
PrivateDefinitions.Add("SQLITE_OS_WIN=1");
PrivateDefinitions.Add("NDEBUG");
PrivateDefinitions.Add("SQLITE_THREADSAFE=1");
PrivateDefinitions.Add("SQLITE_TEMP_STORE=0");
PrivateDefinitions.Add("SQLITE_ENABLE_RTREE=1");
PrivateDefinitions.Add("SQLITE_ENABLE_GEOPOLY=1");
PrivateDefinitions.Add("SQLITE_ENABLE_JSON1=1");
PrivateDefinitions.Add("SQLITE_ENABLE_STMTVTAB=1");
PrivateDefinitions.Add("SQLITE_ENABLE_DBPAGE_VTAB=1");
PrivateDefinitions.Add("SQLITE_ENABLE_DBSTAT_VTAB=1");
PrivateDefinitions.Add("SQLITE_INTROSPECTION_PRAGMAS=1");
PrivateDefinitions.Add("SQLITE_ENABLE_COLUMN_METADATA=1");
PrivateDefinitions.Add("SQLITE_MAX_TRIGGER_DEPTH=100");
PrivateDefinitions.Add("SQLITE_THREAD_OVERRIDE_LOCK=-1");
bEnableUndefinedIdentifierWarnings = false; // The embedded SQLite implementation generates a lot of these warnings
bUseUnity = false; // Ensure the embedded SQLite implementation is always compiled in isolation
}
}
The directory structure to integrate the library as plugin is shown here.
Further information are referred to: