一个.net平台调用的例子

本文介绍一个C#调用C++写的DLL的完整例子,其中DLL的定义中涉及结构体、数组、指针、回调函数,首先做一下大概的介绍:

 

1、数组,C#向DLL传数组实际是传入数组的首地址,即传址(ref)。

2、指针,C#提供专门用于处理指针的类型及Ptr类型,比如用于传递Void * 类型的IntPtr类型。

3、结构体,结构体的传递一般要把结构体进行序列化处理,即在结构体的定义前加上:

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]

4、回调函数,C#提供委托的功能,所以回调函数一般我们用委托来实现,以下是个例子。

 

以下是DLL中各函数、结构体、回调函数的定义:

 

typedef struct _VOCLINK_PARAM {
 TCHAR  sVocIp[16];
 UINT  nPort;
} VOCLINK_PARAM, *PVOCLINK_PARAM;

 

typedef struct _VMCCB_EVT {
 UINT EvtCode;
 UINT RetCode;
 UINT Channel;
 UINT uBufferLen;  // pBuffer 's length
 void* pBuffer;  // Buffer for holding extra info
} VMCCB_EVT, *PVMCCB_EVT;

 

typedef void (*VLVMC_CB)( long VocHandle, const PVMCCB_EVT pVmcEvt, LPARAM lpData );

 

_DLLIMP long CALL_CONVENT
VLVmcOpen( const VLVMC_CB pVmcCB, LPARAM lpData, long *pVmcHandle );

_DLLIMP long CALL_CONVENT
VLVmcClose( long VmcHandle );

// Maximum 30 voice associated with each VMC
_DLLIMP long CALL_CONVENT
VLVmcConnectVoc( long VmcHandle, const PVOCLINK_PARAM pVocSrv, long *pVocHandle );

_DLLIMP long CALL_CONVENT
VLVmcDisconnectVoc( long VocHandle );

 

C#结构体、委托、函数定义代码:

 

 

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct VOCLINK_PARAM
    {
        /// TCHAR[16]
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string  sVocIp;

        /// UINT->unsigned int
        public uint nPort;
    }

 

   

 [StructLayoutAttribute(LayoutKind.Sequential)]
    public struct VMCCB_EVT
    {
        /// UINT->unsigned int
        public uint EvtCode;

        /// UINT->unsigned int
        public uint RetCode;

        /// UINT->unsigned int
        public uint Channel;

        /// UINT->unsigned int
        public uint uBufferLen;

        /// void*
        public IntPtr pBuffer;
    }

 

 

/// Return Type: void
    ///VocHandle: int
    ///pVmcEvt: PVMCCB_EVT->_VMCCB_EVT*
    ///lpData: LPARAM->LONG_PTR->int
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void VLVMC_CB(int VocHandle, ref VMCCB_EVT pVmcEvt, int lpData);

 

public class VMCOperator
    {
        /// Return Type: int
        ///pVmcCB: VLVMC_CB
        ///lpData: LPARAM->LONG_PTR->int
        ///pVmcHandle: int*
        [DllImportAttribute("VLVmc.dll", EntryPoint = "VLVmcOpen", CallingConvention = CallingConvention.StdCall)]
        public static extern int VLVmcOpen(VLVMC_CB pVmcCB, int lpData, ref int pVmcHandle);

        /// Return Type: int
        ///VmcHandle: int
        [DllImportAttribute("VLVmc.dll", EntryPoint = "VLVmcClose", CallingConvention = CallingConvention.StdCall)]
        public static extern int VLVmcClose(int VmcHandle);

        /// Return Type: int
        ///VmcHandle: int
        ///pVocSrv: PVOCLINK_PARAM->_VOCLINK_PARAM*
        ///pVocHandle: int*
        [DllImportAttribute("VLVmc.dll", EntryPoint = "VLVmcConnectVoc", CallingConvention = CallingConvention.StdCall)]
        public static extern int VLVmcConnectVoc(int VmcHandle, ref VOCLINK_PARAM pVocSrv, ref int pVocHandle);

        /// Return Type: int
        ///VocHandle: int
        [DllImportAttribute("VLVmc.dll", EntryPoint = "VLVmcDisconnectVoc", CallingConvention = CallingConvention.StdCall)]
        public static extern int VLVmcDisconnectVoc(int VocHandle);
    }

 

C#调用代码

 

 private int vmc_handler;
        private int voc_handler;
        private VLVMCInterop.VOCLINK_PARAM voc_link_param;
        private VLVMCInterop.VLVMC_CB vmc_cb;

 

 private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            vmc_cb = new VLVMCInterop.VLVMC_CB(OnVLVMC_CB);
            voc_link_param = new VLVMCInterop.VOCLINK_PARAM();
        }

 

 private void btnOpenVMC_Click(object sender, RoutedEventArgs e)
        {
            if (checkInput())
            {
                vmc_handler = 0;
                int lpdata = 0;

                if (VLVMCInterop.VMCOperator.VLVmcOpen(vmc_cb, lpdata, ref vmc_handler) == VLVMCInterop.VMCCodeDefine.VLVMC_ERR_SUCCESS)
                {
                    string vocip = txtVocIP.Text;
                    voc_link_param.sVocIp = vocip;
                    voc_link_param.nPort = Convert.ToUInt32(txtVocPort.Text);
                    voc_handler = 0;
                    if (VLVMCInterop.VMCOperator.VLVmcConnectVoc(vmc_handler, ref voc_link_param, ref voc_handler) == VLVMCInterop.VMCCodeDefine.VLVMC_ERR_SUCCESS)
                    {
                        

                    }
                }
            }
        }

 

 private void OnVLVMC_CB(int voc_handler, ref VLVMCInterop.VMCCB_EVT vmccb_evt, int lpdata)
        {
            uint code = vmccb_evt.EvtCode;
            uint channel = vmccb_evt.Channel;
            switch (code)
            {
               .......

            }
        }

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值