• C#封装C++DLL(特别是char*对应的string)


    1、新建一个C#-Windows-类库(用于创建C#类库(.dll)的项目)类型的工程

    2、对于普通C++函数

    XXXX_API void cppFun(int i);

    在cs代码中添加

    [DllImport("c++xxxx.dll")]

    public static extern void cppFun(int i);

    3、对于C++中的结构体,因为C++中结构体默认访问控制为public,而C#中结构体默认为private,所以要显示指定一下

    typedef struct {
         char sDVRIP[16]; /* DVR IP地址 */
         char sDVRIPMask[16]; /* DVR IP地址掩码 */
         DWORD dwNetInterface; /* 10M/100M自适应,索引 */
         WORD wDVRPort; /* 端口号 */
         BYTE byMACAddr[MACADDR_LEN]; /* 服务器的物理地址 */
     }NET_POSA_ETHERNET;

    C#对应

    public struct NET_POSA_ETHERNET
    {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string sDVRIP; //DVR IP地址
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string sDVRIPMask; // DVR IP地址掩码
    public uint dwNetInterface; //网络接口 1-10MBase-T 2-10MBase-T全双工 3-100MBase-TX 4-100M全双工 5-10M/100M自适应
    public uint wDVRPort; //端口号
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] byMACAddr; //[MACADDR_LEN]; //PPPoE用户名//服务器的物理地址
    }

    将string转为IntPtr:IntPtr System.Runtime.InteropServices.Marshal.StringToCoTaskMemAuto(string)

    将IntPtr转为string:string System.Runtime.InteropServices.MarshalPtrToStringAuto(IntPtr)

    类型对照:

    BSTR ---------  StringBuilder

    LPCTSTR --------- StringBuilder

    LPCWSTR ---------  IntPtr

    handle---------IntPtr

    hwnd-----------IntPtr

    char *----------string

    int * -----------ref int

    int &-----------ref int

    void *----------IntPtr

    unsigned char *-----ref byte

    Struct需要在C#里重新定义一个Struct

    CallBack回调函数需要封装在一个委托里

    typedef void(* CallbackResult)(int progress, char *result);
    extern"C" _declspec(dllexport)
    void subscribe0(char* eventName, CallbackResult callback)
    {
        callback(8, "AAABBB");
    }
    
    C#
    public delegate void CallBack(int progress, string lParam);
    [DllImport("deepstream_for_csharp")]
    public static extern void subscribe0(string eventName, CallBack func);
    CallBack myCallBack = new CallBack(ReportView);
    subscribe0("adsm", myCallBack);
    public static void ReportView(int progress, string lParam)
        {
            Debug.Log("AAAAAA");
        }
    C++:
    EXPORTS_U3DDLL
    void subscribe(char* eventName,void(*func)(const char*))
    {
        if (client == 0)
        {
            std::cout << "client has not been created!!";
            return;
        }
        const deepstream::SubscriptionId event_sub_id =
            client->event.subscribeForUnity(eventName, func);
        subEventID[eventName] = event_sub_id;
    }
    

    SubscriptionId subscribeForUnity(const std::string &name, std::function<void(const char* data)> callback)
    {
    Buffer name_buff(name);
    Event::SubscribeFn core_callback([callback, this](const Buffer &prefixed_buff) {
    const json &data = type_serializer_.prefixed_to_json(prefixed_buff);
    const std::string &data_string(data);
    callback(data_string.c_str());
    });
    SubscriptionId subscription_id = client_.event.subscribe(name_buff, core_callback);
    return subscription_id;
    }

    
    C#:
    [DllImport("deepstream_for_csharp")]
    public static extern void subscribe(string eventName, SubscribeCallBack callback);
    public delegate void SubscribeCallBack(string data);
    public static void eventPosCallBack(string data)
    {
        Debug.Log("pos:" + data+data.Length);
    }
    subscribe("pos", new SubscribeCallBack(eventPosCallBack));
  • 相关阅读:
    php 发送超大数据处理
    Linux 忘记了mysql 密码
    利用mysqldump 实现每天备份方案
    window 下忘记了mysql 密码的解决方法
    MySQL添加字段和修改字段的方法
    php 即使客户端或者服务器断开(如关掉浏览器)脚本也可以继续执行
    PHP面向对象05_接口与多态
    PHP面向对象06_异常处理
    PHP面向对象07_PDO
    PHP面向对象之魔术方法复习
  • 原文地址:https://www.cnblogs.com/coolbear/p/4155403.html
Copyright © 2020-2023  润新知