public void Run() { string gamename = "gmtest"; #if GSI_COMMON_DEBUG gamespyCommonDebug.gsOpenDebugFile("Debug_Sake.log"); gamespyCommonDebug.gsSetDebugLevel(GSIDebugCategory.GSIDebugCat_All, GSIDebugType.GSIDebugType_All, GSIDebugLevel.Hardcore); #endif Console.WriteLine("\n------------ SAKE C# sample ------------------------\n"); if (CheckServices(gamename) != GSIACResult.GSIACAvailable) { Console.WriteLine("{0}: Online services are unavailable now.", gamename); return; } if (Initialize()) { Console.WriteLine("{0}: Initialized.\n", gamename); } else { Terminate(); Console.WriteLine("\n------------ SAKE C# Sample Terminated with Failure ------------------------\n"); Console.WriteLine("Press AnyKey Continue...."); Console.ReadLine(); return; } // sakeGetRecordCount example Console.WriteLine("---------- {0} table : GetRecordCount \n", _tableId); StorageGetRecordCount(_tableId, null, true); // sakeGetMyRecords example Console.WriteLine("--------- {0} table : GetMyRecords\n", _tableId); // Initialize sample data System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); string[] fields = new string[12] { "recordid", "ownerid", "MyByte", "MyShort", "MyInt", "MyFloat", "MyAsciiString", "MyUnicodeString", "MyBoolean", "MyDateAndTime", "MyBinaryData", "MyFileID" }; //gamespySake.SAKEGetMyRecordsInput getMyRecordsInput = new gamespySake.SAKEGetMyRecordsInput(); getMyRecordsInput.mTableId = _tableId; getMyRecordsInput.mNumFields = 12; getMyRecordsInput.mFieldNames = Marshal.AllocHGlobal(getMyRecordsInput.mNumFields * Marshal.SizeOf(typeof(IntPtr))); IntPtr[] pFieldNames = new IntPtr[getMyRecordsInput.mNumFields]; for (int i = 0; i < getMyRecordsInput.mNumFields; i++) { pFieldNames[i] = Marshal.StringToHGlobalAnsi(fields[i]); } Marshal.Copy(pFieldNames, 0, getMyRecordsInput.mFieldNames, getMyRecordsInput.mNumFields); GCHandle hInput = GCHandle.Alloc(getMyRecordsInput); StorageGetMyRecords(getMyRecordsInput); hInput.Free(); // // sakeCreateRecord example Console.WriteLine("--------- {0} table : CreateRecord\n", _tableId); gamespySake.SAKECreateRecordInput createRecordInput = new gamespySake.SAKECreateRecordInput(); gamespySake.SAKEField[] field = new gamespySake.SAKEField[9]; // ownerid, recordid and dateandtime is auto created, do not initialize them // Initialize the field[] array int j = 0; field[j].mName = "MyByte"; field[j].mType = SAKEFieldType.SAKEFieldType_BYTE; field[j].mValue.mByte = 1; j++; field[j].mName = "MyShort"; field[j].mType = SAKEFieldType.SAKEFieldType_SHORT; field[j].mValue.mShort = 2; j++; field[j].mName = "MyInt"; field[j].mType = SAKEFieldType.SAKEFieldType_INT; field[j].mValue.mInt = 3; j++; field[j].mName = "MyFloat"; field[j].mType = SAKEFieldType.SAKEFieldType_FLOAT; field[j].mValue.mFloat = 4.0F; j++; field[j].mName = "MyAsciiString"; field[j].mType = SAKEFieldType.SAKEFieldType_ASCII_STRING; field[j].mValue.mString = new IntPtr(); field[j].mValue.mString = Marshal.StringToHGlobalAnsi("ASCII string"); j++; field[j].mName = "MyUnicodeString"; field[j].mType = SAKEFieldType.SAKEFieldType_UNICODE_STRING; field[j].mValue.mString = new IntPtr(); field[j].mValue.mString = Marshal.StringToHGlobalUni("UNICODE string"); j++; field[j].mName = "MyBoolean"; field[j].mType = SAKEFieldType.SAKEFieldType_BOOLEAN; field[j].mValue.mBoolean = true; j++; field[j].mName = "MyBinaryData"; field[j].mType = SAKEFieldType.SAKEFieldType_BINARY_DATA; field[j].mValue.mBinaryData = new gamespySake.SAKEBinaryData(); field[j].mValue.mBinaryData.mLength = 10; field[j].mValue.mBinaryData.mValue = Marshal.AllocHGlobal(field[j].mValue.mBinaryData.mLength); byte[] binaryData = new byte[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Marshal.Copy(binaryData, 0, field[j].mValue.mBinaryData.mValue, binaryData.Length); j++; field[j].mName = "MyFileID"; field[j].mType = SAKEFieldType.SAKEFieldType_INT; field[j].mValue.mInt = 55555; //Correct way of Marshaling SAKEField array into IntPtr createRecordInput.mTableId = _tableId; createRecordInput.mNumFields = field.Length; // number of elements in the field[] array. // Sake expects all the fields in a continous block of memory. createRecordInput.mFields = Marshal.AllocHGlobal(createRecordInput.mNumFields * Marshal.SizeOf(typeof(gamespySake.SAKEField))); for (int i = 0; i < createRecordInput.mNumFields; i++) { // Obtain the pointer to the specific element in the Unmanaged Memory IntPtr pField = new IntPtr(createRecordInput.mFields.ToInt32() + i * Marshal.SizeOf(typeof(gamespySake.SAKEField))); //Marshal filed[i] to Unmanaged memory Marshal.StructureToPtr(field[i], pField, false); // must delete field[] after the callback returns } // Want to make sure createRecordInput does not get garbage collected. GCHandle hCreateInput = GCHandle.Alloc(createRecordInput); StorageCreateRecord(createRecordInput); hCreateInput.Free(); // Terminate(); Console.WriteLine("\n------------ SAKE C# Sample Completed------------------------\n"); Console.WriteLine("Press Enter Continue...."); Console.ReadLine(); }
public static void storageGetMyRecordsCallback ( IntPtr sake, IntPtr request, // pointer to SAKERequest SAKERequestResult result, IntPtr inputData, IntPtr outputData, IntPtr userData ) { respReceived = true; // we are keeping the record count in userData for this callback. // other applications might keep objects and etc. if (result == SAKERequestResult.SAKERequestResult_SUCCESS) { gamespySake.SAKEGetMyRecordsOutput resp = (gamespySake.SAKEGetMyRecordsOutput)Marshal.PtrToStructure(outputData, typeof(gamespySake.SAKEGetMyRecordsOutput)); //gamespySake.SAKEGetMyRecordsInput req = // (gamespySake.SAKEGetMyRecordsInput)Marshal.PtrToStructure(inputData, typeof(gamespySake.SAKEGetMyRecordsInput)); //User Data Reference Pointer GCHandle handle = GCHandle.FromIntPtr(userData); SakeAppProgram myObject = (SakeAppProgram)handle.Target; //Process the received Data IntPtr[] pRec = new IntPtr[resp.mNumRecords]; Marshal.Copy(resp.mRecords, pRec, 0, resp.mNumRecords); for (int i = 0; i < resp.mNumRecords; i++) { // Process a Record Console.WriteLine("---------Record[{0}]--------- ", i); for (int j = 0; j < getMyRecordsInput.mNumFields; j++) { // Each record is block of memory which contains the fields (Name,Value,Type) gamespySake.SAKEField aSakefield = new gamespySake.SAKEField(); IntPtr pSakeField = new IntPtr(pRec[i].ToInt32() + j * Marshal.SizeOf(aSakefield)); aSakefield = (gamespySake.SAKEField)Marshal.PtrToStructure(pSakeField, typeof(gamespySake.SAKEField));; switch (aSakefield.mType) { case SAKEFieldType.SAKEFieldType_ASCII_STRING: String myAsciiString = Marshal.PtrToStringAnsi(aSakefield.mValue.mString); Console.WriteLine("{0}[{1}]={2}\n", aSakefield.mName, aSakefield.mType, myAsciiString); break; case SAKEFieldType.SAKEFieldType_UNICODE_STRING: String myUnicodeString = Marshal.PtrToStringUni(aSakefield.mValue.mString); Console.WriteLine("{0}[{1}]={2}\n", aSakefield.mName, aSakefield.mType, myUnicodeString); break; case SAKEFieldType.SAKEFieldType_SHORT: Console.WriteLine("{0}[{1}]={2}\n", aSakefield.mName, aSakefield.mType, aSakefield.mValue.mShort); break; case SAKEFieldType.SAKEFieldType_INT: Console.WriteLine("{0}[{1}]={2}\n", aSakefield.mName, aSakefield.mType, aSakefield.mValue.mInt); break; case SAKEFieldType.SAKEFieldType_FLOAT: Console.WriteLine("{0}[{1}]={2}\n", aSakefield.mName, aSakefield.mType, aSakefield.mValue.mFloat); break; case SAKEFieldType.SAKEFieldType_BYTE: Console.WriteLine("{0}[{1}]={2}\n", aSakefield.mName, aSakefield.mType, aSakefield.mValue.mByte); break; case SAKEFieldType.SAKEFieldType_BINARY_DATA: Console.Write("{0}[{1}]=", aSakefield.mName, aSakefield.mType); if (aSakefield.mValue.mBinaryData.mValue != IntPtr.Zero) { IntPtr pBinaryData = aSakefield.mValue.mBinaryData.mValue; byte[] binaryData = new byte[aSakefield.mValue.mBinaryData.mLength]; Marshal.Copy(pBinaryData, binaryData, 0, binaryData.Length); for (int k = 0; k < binaryData.Length; k++) { Console.Write(" {0} ", binaryData[k]); } Console.WriteLine("\n"); } else { Console.WriteLine("Null\n"); } break; case SAKEFieldType.SAKEFieldType_BOOLEAN: Console.WriteLine("{0}[{1}]={2} \n", aSakefield.mName, aSakefield.mType, aSakefield.mValue.mBoolean); break; case SAKEFieldType.SAKEFieldType_DATE_AND_TIME: Console.WriteLine("{0}[{1}]={2}\n", aSakefield.mName, aSakefield.mType, ConvertFromSeconds(aSakefield.mValue.mDateAndTime).ToString()); break; case SAKEFieldType.SAKEFieldType_INT64: Console.WriteLine("{0}[{1}]={2} \n", aSakefield.mName, aSakefield.mType, aSakefield.mValue.mInt64); break; default: break; } } } Console.WriteLine("SUCCESS: Retrived {0} records\n", resp.mNumRecords); } else { Console.WriteLine("FAILURE: {0}\n", result); } }