• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
蓝色的大海
我很卑微.
博客园    首页    新随笔    联系   管理    订阅  订阅

托管和非托管类型交互的问题

 

 

这是非托管代码封装的结构体:

 typedef struct structural_MEDIA_MOTION_INFO

         {                                              

         DWORD dwEnable;

         DWORD dwRangeCount;

         DWORD dwRange[3][4];

         DWORD dwSensitive[3];

         } MEDIA_MOTION_INFO;

  

这是非托管代码中的函数原型:

void KGetMotionInfo(HANDLE h, MEDIA_MOTION_INFO* MotionInfo)

做法一: 

把非托管结构体封装成托管结构体

[StructLayout(LayoutKind.Sequential, Pack=1)]

        public struct MediaMotionInfo

        {

            public Int32 dwEnable;

            public Int32 dwRangeCount;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public int[] dwRange;

            [MarshalAs(UnmanagedType.ByValArray,SizeConst = 3)] public int[] dwSensitive;

        }

 

因为非托管代码要求地址传递(MEDIA_MOTION_INFO*),所以本处用(ref MediaMotionInfo)

/// <summary>

        /// Get the Server’s Motion setting value.

        /// </summary>

        /// <param name="h">[in] The handle returned by KOpenInterface()</param>

       /// <param name="MotionInfo">[out] the Motion information on the video server.</param>

        [DllImport(DLLFILE, EntryPoint = "KGetMotionInfo")]

        public static extern void GetMotionInfo(IntPtr h,ref MediaMotionInfo MotionInfo);

 

调用结果正确 mmi属性是[out],所以可以得到正确的结果结构体。

private void getMotionButton_Click(object sender, EventArgs e)

        {

                mmi = new Acti10000Sdk.MediaMotionInfo();

                Acti10000Sdk.GetMotionInfo(h, ref mmi);

            }

        }

此图反映值类型托管和非托管之间的引用传递:

解决方法二:

我把非托管的结构体封装成一个类,结构如下:

[StructLayout(LayoutKind.Sequential, Pack = 1)]

public class MediaMotionInfo

{

    public Int32 dwEnable;

    public Int32 dwRangeCount;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]

    public int[] dwRange=new int[12];

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]

    public int[] dwSensitive=new int[3];

}

 

由于我封装的是个类,所以直接写MediaMotionInfo就是引用类型,我认为此处和非托管代码也是匹配的。

/// <summary>

        /// Get the Server’s Motion setting value.

        /// </summary>

        /// <param name="h">[in] The handle returned by KOpenInterface()</param>

        /// <param name="MotionInfo">[out] the Motion information on the video server.</param>

        [DllImport(DLLFILE, EntryPoint = "KGetMotionInfo")]

        public static extern void GetMotionInfo(IntPtr h,  MediaMotionInfo MotionInfo);

 

此处参数为一个类的引用,指向堆的上的对象。问题是这样做为什么得不到返回的类呢?

private void getMotionButton_Click(object sender, EventArgs e)

        {

                mmi = new Acti10000Sdk.MediaMotionInfo();

                Acti10000Sdk.GetMotionInfo(h, mmi);

            }

        }

 此图反映引用类型在托管和非托管的值传递:

 

问题:第二种方法哪里错了。

 

posted @ 2008-09-25 16:53  blue th  阅读(1411)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3