C#调用EasyPusher

来源:互联网 发布:域名服务器地址是什么 编辑:程序博客网 时间:2024/06/03 23:49

大家好,本人刚毕业程序猿一枚。受人所托,第一次写博客,如有错误之处敬请谅解。本文主要讲解:如何在C#中封装以及调用C++编写的函数,通过对EasyDarwin开源流媒体的EasyPusher为例讲解。

       首先,我个人不喜欢复杂的调用,比如很多C#中Marshal类相关的操作。我更愿意把c++代码封装成对象,以对象void*到IntPtr的相互转换来实现。 当然,这种方法对于需要传递复杂的数据结构来说,显然还是有其缺点的,比如:在opencv中,我就不知道如何传递mat图片委屈

    本文将用极少的代码来说明。有源码哦!

//----------------------------------------------------华丽的分割线---------------------------------------------------

用过EasyPusher的人都知道,在一个main函数中,实现了推流。调用十分简单!!!而我们要做的:

        第一步:将EasyPusher的main函数构成封装成一个类,暴露可供调用的函数即可,如RTSPPusher类,实现函数见源码。

class RTSPPusher {private:       void* rtspHandle;//rtsp源拉流句柄void* pusherHandle;//推流句柄char* PusherServerIP;//推送的服务器IPint PusherServerPort;//推送的服务器端口char* PusherTailName;//推送的rtsp的后缀名char* srcRtspAddr; //源rtsp流地址        EASY_MEDIA_INFO_T*fSourceMediaInfo;//媒体信息public:RTSPPusher(const char* pushServerIP, int pushServerPort, const char* tailName, const char* sourceRtsp);    virtual ~RTSPPusher();     bool OnCreatePusher(); bool OnClosePusher();        public:    //rtsp对象拉流回调    void OnRtspSrcCall( int _mediatype, char *pbuf, RTSP_FRAME_INFO *frameinfo);    //推送器回馈消息    void OnPusherCall(int _id, EASY_PUSH_STATE_T _state, EASY_AV_Frame *_frame);};
         第二步:建立一个c++的管理方法,其实就是导出函数,用来让外部调用(c++、c#调用)。此处只贴头文件,实现见源码。
#pragma once#include <Windows.h>extern "C"{#define LIB_PUSH_API __declspec(dllexport)///创建并且开启推流LIB_PUSH_API void* CreateStartPush(const char* pushServerIP, int pushServerPort, const char* tailName, const char* sourceRtsp);//停止推流LIB_PUSH_API bool ClosePush(void* senderObjPtr);}
      由此,我们只要调用void* CreateStartPush(const char* pushServerIP, int pushServerPort, const char* tailName, const char* sourceRtsp);函数就能创建一个推流对象,实现推流,并返回此对象的地址void*。在c#中用Intptr保存。至此,c++对EasyPusher的封装就算完成了。当然,如果觉得封装太简单,那就是仁者见仁了,自由修改就行啦。

 第三步:如何把第二步的c++函数定义代码转换成C#的呢?在此提供一个工具点击打开链接


        拷贝代码到C#中,把调用的dll名字改下,如下:(注意:函数我添加了一句:CallingConvention = CallingConvention.Cdecl),自己百度一下吧。

using System;using System.Collections.Generic;using System.Linq;using System.Runtime.InteropServices;using System.Text;namespace ConsolePusher{    public class PusherSDK    {        const string dllName = "libPushCplus.dll";        /// Return Type: void*        ///pushServerIP: char*        ///pushServerPort: int        ///tailName: char*        ///sourceRtsp: char*        [System.Runtime.InteropServices.DllImportAttribute(dllName, EntryPoint = "CreateStartPush", CallingConvention = CallingConvention.Cdecl)]        public static extern System.IntPtr CreateStartPush([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string pushServerIP, int pushServerPort, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string tailName, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string sourceRtsp);        /// Return Type: boolean        ///senderObjPtr: void*        [System.Runtime.InteropServices.DllImportAttribute(dllName, EntryPoint = "ClosePush", CallingConvention = CallingConvention.Cdecl)]        [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.I1)]        public static extern bool ClosePush(System.IntPtr senderObjPtr);    }}

    第四步:到此,我们封装好了c++,并且得到了c#掉用c++导出函数的方法。我们只需编程就好啦。具体见c#源码的main函数。实现源码点击打开链接

总结:第一次写博客,大家别笑话哈。如过大家觉得还行,我也试试博客,偶尔写写一些平时的积累。这篇博客比较简单,主要点在EasyPusher的使用;导出函数的声明方法;c++函数如何转换为c#。

注:本博客中的代码仅供学习交流使用,如有侵权,请及时删除。还有就是由于工作原因,如有疑问可能无法回复。

      

1 0
原创粉丝点击