zoukankan      html  css  js  c++  java
  • Passing structures between C# and C/C++

    Data structures can be passed between managed C# code and unmanaged C/C++ dynamic link libraries but it can be a little complicated. The trick is to define structures that match between the two different languages; and perhaps write wrapper functions that hide away the complexity of the memory marshaling code. I will show a couple of simple examples of passing a system time data structure from C/C++ to C# and vice versa here.

    The C/C++ definition of the system time structure is as follows:

    typedef struct _SYSTEMTIME {
        WORD wYear;
        WORD wMonth;
        WORD wDayOfWeek;
        WORD wDay;
        WORD wHour;
        WORD wMinute;
        WORD wSecond;
        WORD wMilliseconds;
    } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;


    The matching C# equivalent of the system time structure can be defined as shown below.

    private struct SYSTEMTIME
    {
        public UInt16 wYear;
        public UInt16 wMonth;
        public UInt16 wDayOfWeek;
        public UInt16 wDay;
        public UInt16 wHour;
        public UInt16 wMinute;
        public UInt16 wSecond;
        public UInt16 wMilliseconds;
    }


    Example 1: Passing a structure from C/C++ to C#
    If the C/C++ function has the following signature:

    HRESULT GetDateTime( HANDLE hClient, SYSTEMTIME* pSysTime );


    Then the following wrapper functions can be used to call the C/C++ function.

    [DllImport("MyDynamicLinkLib.dll")]
    private static extern int GetDateTime(IntPtr hClient, IntPtr pSysTime);
    public static int GetDateTime(IntPtr hClient, out DateTime sysTime)
    {
        int hr = 0;
        IntPtr pSysTime = IntPtr.Zero;
        SYSTEMTIME theTime = new SYSTEMTIME();
        sysTime = new DateTime();
        pSysTime = Marshal.AllocHGlobal( Marshal.SizeOf(theTime));
        hr = GetDateTime(hClient, pSysTime);
        theTime = (SYSTEMTIME) Marshal.PtrToStructure(pSysTime, typeof(SYSTEMTIME));
        Marshal.FreeHGlobal(pSysTime);
        sysTime = new DateTime(theTime.wYear, theTime.wMonth, theTime.wDay, theTime.wHour, theTime.wMinute, theTime.wSecond, theTime.wMilliseconds);
        return hr;
    }


    To use the wrapper functions, simply do something like the following:

    IntPtr hClient = IntPtr.Zero;
    DateTime dt = new DateTime();
    int ret = GetDateTime( hClient, out dt);

      


    Example 2: Passing a structure from C# to C/C++
    If the C/C++ function has the following signature,

    HRESULT SetDateTime( HANDLE hClient, SYSTEMTIME* pSysTime );


    Then the following wrapper functions can be used to call the C/C++ function.

    [DllImport("MyDynamicLinkLib.dll")]
    private static extern int SetDateTime(IntPtr hClient, IntPtr pSysTime);
    public static int SetDateTime(IntPtr hClient, DateTime sysTime)
    {
        int hr = 0;
        IntPtr pSysTime = IntPtr.Zero;
        SYSTEMTIME theTime = new SYSTEMTIME();
        theTime.wYear = (ushort) sysTime.Year;
        theTime.wMonth = (ushort) sysTime.Month;
        theTime.wDay = (ushort) sysTime.Day;
        theTime.wDayOfWeek = (ushort) sysTime.DayOfWeek;
        theTime.wHour = (ushort) sysTime.Hour;
        theTime.wMinute = (ushort) sysTime.Minute;
        theTime.wSecond = (ushort) sysTime.Second;
        theTime.wMilliseconds = (ushort) sysTime.Millisecond;
        pSysTime = Marshal.AllocHGlobal(Marshal.SizeOf(theTime));
        hr = SetDateTime(hClient, pSysTime);
        Marshal.FreeHGlobal(pSysTime);
        return hr;
    }


    Do the following to call the wrapper functions.

    DateTime dt = new DateTime();
    int hr = SetDateTime(hClient, dt);
  • 相关阅读:
    我修改/收藏的CSDN知识.(asp.net JavaScript)
    哪里摔倒就在哪里躺下
    显示存储过程的名称、创建时间、修改时间
    Flash Builder 初试(二)绑定和双向绑定
    C#支持中文的格式化字符长度方法
    Flash Builder 初试(一)信息提示窗口
    Flash Builder 初试(三) 使用摄像头
    Null Object 模式
    开放封闭原则(OCP)
    面向对象设计5大准则
  • 原文地址:https://www.cnblogs.com/stoneG/p/6689938.html
Copyright © 2011-2022 走看看