locked
How to call CreateFontPackage method from FontSub.dll

    Question

  • Hi everybody,

    Here is piece of code:

            [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            internal delegate IntPtr ALLOCPROC(Int32 Size);
    
            [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            internal delegate IntPtr REALLOCPROC(IntPtr MemBlock, Int32 Size);
    
            [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            internal delegate IntPtr FREEPROC(IntPtr MemBlock);
    
            [DllImport("FontSub.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
            internal static extern ulong CreateFontPackage(
                byte[] puchSrcBuffer,
                ulong ulSrcBufferSize,
                [Out, MarshalAs(UnmanagedType.LPArray)] out byte[] puchFontPackageBuffer,
                out  ulong pulFontPackageBufferSize,
                out  ulong pulBytesWritten,
                ushort usFlags,
                ushort usTTCIndex,
                ushort usSubsetFormat,
                ushort usSubsetLanguage,
                ushort usSubsetPlatform,
                ushort usSubsetEncoding,
                ushort[] pusSubsetKeepList,
                ushort usSubsetKeepListCount,
                ALLOCPROC lpfnAllocate,
                REALLOCPROC lpfnReAllocate,
                FREEPROC lpfnFree,
                IntPtr lpvReserved
                );
    
    and I call it in following way:

                                ALLOCPROC allocproc = new ALLOCPROC(__alloc);
                                REALLOCPROC reallocproc = new REALLOCPROC(__realloc);
                                FREEPROC freeproc = new FREEPROC(__free);
                                ushort[] subset = { };
                                byte[] buffer = { };
                                ulong buffer_size, bytes_written;
    
                                ulong rc = CreateFontPackage(
                                    result, (ulong)result.Length,
                                    out buffer, out buffer_size, out bytes_written,
                                    /* flags */ 0,
                                    0, /* TTC index is used only if  */
                                    0, /*  TTFCFP_SUBSET */
                                    0, /* Subset langugage */
                                    0, /* Subset platform: TTFCFP_UNICODE_PLATFORMID */
                                    1, /* Subset encoding: TTFCFP_UNICODE_CHAR_SET */
                                    subset,
                                    (ushort)subset.Length,
                                    allocproc, reallocproc, freeproc, (IntPtr)0);
    
    error code is: 0x02d8bf200000044e  (Calling function parameter 2 was invalid.)

    How to call CreateFontPackage from C# code?

    Friday, February 26, 2010 6:03 PM

Answers

  • Couple of changes here.

    1) unsigned long in C++ land is unsigned int.
    2) I don't know where you get __alloc et al so I used Marshal instead.

    It executes successfully, but I didn't test if it actually did what it's supposed to.

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    
    class Program
    {
        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        internal delegate IntPtr ALLOCPROC(Int32 Size);
    
        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        internal delegate IntPtr REALLOCPROC(IntPtr MemBlock, IntPtr Size);
    
        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        internal delegate void FREEPROC(IntPtr MemBlock);
    
        [DllImport("FontSub.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
        internal static extern uint CreateFontPackage(
            [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
            byte[] puchSrcBuffer,
            uint ulSrcBufferSize,
            [Out, MarshalAs(UnmanagedType.LPArray)]
            out byte[] puchFontPackageBuffer,
            out uint pulFontPackageBufferSize,
            out uint pulBytesWritten,
            ushort usFlags,
            ushort usTTCIndex,
            ushort usSubsetFormat,
            ushort usSubsetLanguage,
            ushort usSubsetPlatform,
            ushort usSubsetEncoding,
            [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)]
            ushort[] pusSubsetKeepList,
            ushort usSubsetKeepListCount,
            ALLOCPROC lpfnAllocate,
            REALLOCPROC lpfnReAllocate,
            FREEPROC lpfnFree,
            IntPtr lpvReserved
            );
    
        static void Main(string[] args)
        {
            byte[] result = File.ReadAllBytes(@"C:\Windows\Fonts\Arial.ttf");
            
            ALLOCPROC allocproc = new ALLOCPROC(Marshal.AllocHGlobal);
            REALLOCPROC reallocproc = new REALLOCPROC(Marshal.ReAllocHGlobal);
            FREEPROC freeproc = new FREEPROC(Marshal.FreeHGlobal);
            ushort[] subset = { };
            byte[] buffer;
            uint buffer_size, bytes_written;
    
            uint rc = CreateFontPackage(
                result, (uint)result.Length,
                out buffer, out buffer_size, out bytes_written,
                /* flags */ 0,
                0, /* TTC index is used only if  */
                0, /*  TTFCFP_SUBSET */
                0, /* Subset langugage */
                0, /* Subset platform: TTFCFP_UNICODE_PLATFORMID */
                1, /* Subset encoding: TTFCFP_UNICODE_CHAR_SET */
                subset,
                (ushort)subset.Length,
                allocproc, reallocproc, freeproc, (IntPtr)0);
            if (rc != 0)
                Console.WriteLine("Failed with code {0}", rc);
            else
                Console.WriteLine("Success.");
        }
    }
    
    Saturday, February 27, 2010 3:49 PM

All replies

  • Couple of changes here.

    1) unsigned long in C++ land is unsigned int.
    2) I don't know where you get __alloc et al so I used Marshal instead.

    It executes successfully, but I didn't test if it actually did what it's supposed to.

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    
    class Program
    {
        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        internal delegate IntPtr ALLOCPROC(Int32 Size);
    
        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        internal delegate IntPtr REALLOCPROC(IntPtr MemBlock, IntPtr Size);
    
        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        internal delegate void FREEPROC(IntPtr MemBlock);
    
        [DllImport("FontSub.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
        internal static extern uint CreateFontPackage(
            [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
            byte[] puchSrcBuffer,
            uint ulSrcBufferSize,
            [Out, MarshalAs(UnmanagedType.LPArray)]
            out byte[] puchFontPackageBuffer,
            out uint pulFontPackageBufferSize,
            out uint pulBytesWritten,
            ushort usFlags,
            ushort usTTCIndex,
            ushort usSubsetFormat,
            ushort usSubsetLanguage,
            ushort usSubsetPlatform,
            ushort usSubsetEncoding,
            [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)]
            ushort[] pusSubsetKeepList,
            ushort usSubsetKeepListCount,
            ALLOCPROC lpfnAllocate,
            REALLOCPROC lpfnReAllocate,
            FREEPROC lpfnFree,
            IntPtr lpvReserved
            );
    
        static void Main(string[] args)
        {
            byte[] result = File.ReadAllBytes(@"C:\Windows\Fonts\Arial.ttf");
            
            ALLOCPROC allocproc = new ALLOCPROC(Marshal.AllocHGlobal);
            REALLOCPROC reallocproc = new REALLOCPROC(Marshal.ReAllocHGlobal);
            FREEPROC freeproc = new FREEPROC(Marshal.FreeHGlobal);
            ushort[] subset = { };
            byte[] buffer;
            uint buffer_size, bytes_written;
    
            uint rc = CreateFontPackage(
                result, (uint)result.Length,
                out buffer, out buffer_size, out bytes_written,
                /* flags */ 0,
                0, /* TTC index is used only if  */
                0, /*  TTFCFP_SUBSET */
                0, /* Subset langugage */
                0, /* Subset platform: TTFCFP_UNICODE_PLATFORMID */
                1, /* Subset encoding: TTFCFP_UNICODE_CHAR_SET */
                subset,
                (ushort)subset.Length,
                allocproc, reallocproc, freeproc, (IntPtr)0);
            if (rc != 0)
                Console.WriteLine("Failed with code {0}", rc);
            else
                Console.WriteLine("Success.");
        }
    }
    
    Saturday, February 27, 2010 3:49 PM
  • Thank you very much.
    Sunday, February 28, 2010 11:57 AM