private static void UpdateWeights(IntPtr weightUpdaterHandle, IReadOnlyList <IReadOnlyList <string> > tuneTargetCorpus, HashSet <TranslationInfo>[] nbestLists, float[] curWeights) { IntPtr[] nativeTuneTargetCorpus = tuneTargetCorpus.Select(Thot.ConvertStringsToNativeUtf8).ToArray(); int sizeOfPtr = Marshal.SizeOf <IntPtr>(); int sizeOfDouble = Marshal.SizeOf <double>(); IntPtr nativeNBestLists = Marshal.AllocHGlobal(nbestLists.Length * sizeOfPtr); IntPtr nativeScoreComps = Marshal.AllocHGlobal(nbestLists.Length * sizeOfPtr); var nativeNBestListLens = new uint[nbestLists.Length]; for (int i = 0; i < nbestLists.Length; i++) { IntPtr nativeNBestList = Marshal.AllocHGlobal(nbestLists[i].Count * sizeOfPtr); IntPtr nativeListScoreComps = Marshal.AllocHGlobal(nbestLists[i].Count * sizeOfPtr); int j = 0; foreach (TranslationInfo ti in nbestLists[i]) { IntPtr nativeSegment = Thot.ConvertStringsToNativeUtf8(ti.Translation); Marshal.WriteIntPtr(nativeNBestList, j * sizeOfPtr, nativeSegment); IntPtr nativeTransScoreComps = Marshal.AllocHGlobal((ti.ScoreComponents.Length - 1) * sizeOfDouble); Marshal.Copy(ti.ScoreComponents, 0, nativeTransScoreComps, ti.ScoreComponents.Length - 1); Marshal.WriteIntPtr(nativeListScoreComps, j * sizeOfPtr, nativeTransScoreComps); j++; } Marshal.WriteIntPtr(nativeNBestLists, i * sizeOfPtr, nativeNBestList); Marshal.WriteIntPtr(nativeScoreComps, i * sizeOfPtr, nativeListScoreComps); nativeNBestListLens[i] = (uint)nbestLists[i].Count; } try { Thot.llWeightUpdater_updateClosedCorpus(weightUpdaterHandle, nativeTuneTargetCorpus, nativeNBestLists, nativeScoreComps, nativeNBestListLens, curWeights, (uint)nbestLists.Length, (uint)curWeights.Length - 1); } finally { foreach (IntPtr nativeSegment in nativeTuneTargetCorpus) { Marshal.FreeHGlobal(nativeSegment); } for (int i = 0; i < nbestLists.Length; i++) { IntPtr nativeNBestList = Marshal.ReadIntPtr(nativeNBestLists, i * sizeOfPtr); IntPtr nativeListScoreComps = Marshal.ReadIntPtr(nativeScoreComps, i * sizeOfPtr); for (int j = 0; j < nbestLists[i].Count; j++) { IntPtr nativeSegment = Marshal.ReadIntPtr(nativeNBestList, j * sizeOfPtr); Marshal.FreeHGlobal(nativeSegment); IntPtr nativeTransScoreComps = Marshal.ReadIntPtr(nativeListScoreComps, j * sizeOfPtr); Marshal.FreeHGlobal(nativeTransScoreComps); } Marshal.FreeHGlobal(nativeNBestList); Marshal.FreeHGlobal(nativeListScoreComps); } Marshal.FreeHGlobal(nativeNBestLists); Marshal.FreeHGlobal(nativeScoreComps); } }