C#与C++回调交互
来源:互联网 发布:淘宝店面怎么装修 编辑:程序博客网 时间:2024/05/16 17:17
先总结一部分
using System.Collections;using System.Collections.Generic;using System.Runtime.InteropServices;using UnityEngine;public class InstructionDLL{ /* * C/C++ * typedef void (*DPNewCallIn) (HANDLE hSession, DPMedia * pMedia); * typedef void (*DPSessionError) (HANDLE hSession, char * strError); * typedef void (*DPNewMessage) (char * msginfo, int rip); * typedef void (*DPRemoteHangUp) (HANDLE hSession); * * 注册回调函数 * extern "C" __declspec(dllexport) void RegistCallBackFunc(DPNewCallIn cbNewCallIn, DPSessionError cbSessionError, DPNewMessage cbNewMessage, DPRemoteHangUp cbRemoteHangUp); * * 第一个回调方法参数里面的结构体定义: * typedef struct * { * int nVideo; * int nAudio; * unsigned char Description[]; * } DPMedia * * C#关键代码: */ //注册回调函数 [DllImport("DPCall2.dll", CallingConvention = CallingConvention.StdCall)] public static extern void RegistCallBackFunc(NewCallInCallbackDelegate cbNewCallIn, CallErrorCallbackDelegate cbSessionError, CallNewMessageCallbackDelegate cbNewMessage, RemoteHangUpCallbackDelegate cbRemoteHangUp); //设置委托 [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall, CharSet = CharSet.Ansi)] public delegate void NewCallInCallbackDelegate(int hSession, ref DpMedia pMedia); [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall, CharSet = CharSet.Ansi)] public delegate void CallErrorCallbackDelegate(int hSession, [MarshalAs(UnmanagedType.LPArray, SizeConst = 8000)]byte[] strError); [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall, CharSet = CharSet.Ansi)] public delegate void CallNewMessageCallbackDelegate([MarshalAs(UnmanagedType.LPArray, SizeConst = 8000)]byte[] msg, int rip); [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall, CharSet = CharSet.Ansi)] public delegate void RemoteHangUpCallbackDelegate(int hSession); public struct DataListener { public NewCallInCallbackDelegate OnNewCallInEvent; public CallErrorCallbackDelegate OnCallErrorEvent; public CallNewMessageCallbackDelegate OnCallNewMessageEvent; public RemoteHangUpCallbackDelegate OnRemoteHangUpEvent; public DataListener(NewCallInCallbackDelegate newCall,CallErrorCallbackDelegate callError, CallNewMessageCallbackDelegate callNewMessage,RemoteHangUpCallbackDelegate remoteHang) { OnNewCallInEvent = newCall; OnCallErrorEvent = callError; OnCallNewMessageEvent = callNewMessage; OnRemoteHangUpEvent = remoteHang; } } /* * 第二种为直接调用Dll文件,放入Plugins下 * * [DllImport("CSharpUseCDLL")] * private static extern void fun0(ref int a); */}public class VisionListener{ InstructionDLL.DataListener dataListener; public void Init() { dataListener = new InstructionDLL.DataListener(NewCallInCallbackDelegate, CallErrorCallbackDelegate, CallNewMessageCallbackDelegate, RemoteHangUpCallbackDelegate); } void NewCallInCallbackDelegate(int hSession, ref DpMedia pMedia) { } void CallErrorCallbackDelegate(int hSession, byte[] strError) { } void CallNewMessageCallbackDelegate(byte[] msg, int rip) { } void RemoteHangUpCallbackDelegate(int hSession) { }}[StructLayout(LayoutKind.Sequential)]public struct DpMedia{ public int nVideo; public int nAudio; [MarshalAs(UnmanagedType.LPArray, SizeConst = 4)] public byte[] Description;}
1. 不返回值的参数 C++ 原型: * bool SendNewSms(char *szTel, char *szMessage); * C#引用; * [DllImport( "CdmaCard.dll",EntryPoint="SendNewSms")] * public static extern bool SendNewSms(string phone,string msg); * 2. 带返回值(char *) C++原型: * BOOL GetCardErrorMessage(char *szErrorMessage , int errorCode); C#引用 * [DllImport( "CdmaCard.dll",EntryPoint="GetCardErrorMessage")] * public static extern int GetCardErrorMessage(StringBuilder msg,int errorCode); * StringBuilder buf = new StringBuilder(1024);//指定的Buf大小必须大于可能的最大长度 * GetCardErrorMessage(buf,1); * 3. 带返回值(其他类型) C++原型: * BOOL GetSmsSaveStation (int *nSmsStation); C#引用 * [DllImport( "CdmaCard.dll",EntryPoint="GetSmsSaveStation")] * public static extern bool GetSmsSaveStation(ref int nStation); * 4. 传递结构体指针(C++填充) C++原型: * struct NET_INFO_STRUCT * { * DWORD nDurationTime; //持续时间 double nReceiveByte; //接收字节 double nSendByte; //发送字节 * }; * BOOL NetGetConnectDetail(NET_INFO_STRUCT *lpNetInfo); C#引用 * public struct NET_INFO_STRUCT * { * public uint nDurationTime; //持续时间 * public double nReceiveByte; //接收字节 * public double nSendByte; //发送字节 * } * [DllImport( "CdmaCard.dll",EntryPoint="NetGetConnectDetail")] * public static extern int NetGetConnectDetail(ref NET_INFO_STRUCT pNetInfo); * NET_INFO_STRUCT netInfo = new NET_INFO_STRUCT(); * NetGetConnectDetail(ref netInfo); * 5. 传递结构体数组(C++来填充) C++原型: * struct UIM_BOOK_STRUCT * { * int UimIndex; * char szName[15]; * char szPhone[21]; * }; * int ReadUimAllBook(UIM_BOOK_STRUCT lpUimBookItem[],int nMaxArraySize); C#引用 * [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]//可以指定编码类型 * public struct UIM_BOOK_STRUCT * { * public int UimIndex; * [MarshalAs(UnmanagedType.ByValTStr, SizeConst= 15)] * public string szName; * [MarshalAs(UnmanagedType.ByValTStr, SizeConst= 21)] * public string szPhone; * }; * [DllImport( "CdmaCard.dll",EntryPoint="ReadUimAllBook")] * public static extern int ReadUimAllBook([Out] UIM_BOOK_STRUCT [] lpUimBookItem,int nMaxArraySize); * UIM_BOOK_STRUCT[] p = new UIM_BOOK_STRUCT[20]; int ret = ReadUimAllBook(p,p.Length); * * 6. 注意问题 * 类型不一致,会导致调用失败, * (1) long 类型,在C++中是4字节的整数,在C#中是8字节的整数; * (2) 字符串类型的设置不正确; 以下是几个简单的window调用 * * [System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously * [DllImport("User32.dll", CharSet=CharSet.Auto)] * public static extern bool ScreenToClient(IntPtr hWnd, ref System.Drawing.Point rect); * * [System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously * [DllImport("User32.dll", CharSet=CharSet.Auto)] * public static extern bool GetWindowRect(IntPtr hWnd, out System.Drawing.Rectangle rect); * * [System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously * [DllImport("User32.dll", CharSet=CharSet.Auto)] * public static extern bool UnregisterClass([MarshalAs(UnmanagedType.LPTStr)] string className, IntPtr instanceHandle); * 1. 如果函数只有传入参数,比如: C/C++ Code C++中的输出函数 * int __declspec(dllexport) test(const int N) * { * return N+10; * } * * 对应的C#代码为: C# Code * [DllImport("test.dll", EntryPoint = "#1")] * public static extern int test(int m); * * private void button1_Click(object sender, EventArgs e) * { * textBox1.Text= test(10).ToString(); * } * * * 2. 如果函数有传出参数,比如: C/C++ Code C++ * void __declspec(dllexport) test(const int N, int& Z) * { * Z=N+10; * } * * 对应的C#代码: C# Code * [DllImport("test.dll", EntryPoint = "#1")] * public static extern double test(int m, ref int n); * private void button1_Click(object sender, EventArgs e) * { * int N = 0; * test1(10, ref N); * textBox1.Text= N.ToString(); * } * * * 3. 带传入数组: C/C++ Code * void __declspec(dllexport) test(const int N, const int n[], int& Z) * { * for (int i=0; i<N; i++) * { * Z+=n[i]; * } * } * * C#代码: C# Code * [DllImport("test.dll", EntryPoint = "#1")] * public static extern double test(int N, int[] n, ref int Z); * private void button1_Click(object sender, EventArgs e) * { * int N = 0; * int[] n; * n = new int[10]; * for (int i = 0; i < 10; i++) * { * n[i] = i * } * test(n.Length, n, ref N); * textBox1.Text= N.ToString(); * } * * * 4. 带传出数组: C++不能直接传出数组,只传出数组指针, C/C++ Code * void __declspec(dllexport) test(const int M, const int n[], int *N) * { * for (int i=0; i<M; i++) * { * N[i]=n[i]+10; * } * } * * 对应的C#代码: C# Code * [DllImport("test.dll", EntryPoint = "#1")] * public static extern void test(int N, int[] n, [MarshalAs(UnmanagedTyp e.LPArray,SizeParamIndex=1)] int[] Z); * private void button1_Click(object sender, EventArgs e) * { * int N = 1000; * int[] n, Z; * n = new int[N];Z = new int[N]; * for (int i = 0; i < N; i++) * { * n[i] = i * } * test(n.Length, n, Z); * for (int i=0; i<Z.Length; i++) * { * textBox1.AppendText(Z[i].ToString()+"n"); * } * } * * 这里声明函数入口时,注意这 句 [MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)] int[] Z * 在C#中数组是直接使用的,而在C++中返回的是数组的指针,这句用来转化这两种不同的类型. * * * 5. 传出字符数组: C++定义: C/C++ Code * void __declspec(dllexport) test(int i, double &a, double &b, char t [5]) * * C#对应声明: C# Code * [DllImport("dll.dll", EntryPoint = "test")] * public static extern void test(int i, ref double a, ref double b, [Ou t, MarshalAs(UnmanagedType.LPArray)] char[] t); * char[] t = new char[5]; * test(i, ref a, ref b, t); * * 字符数组的传递基本与4相似,只是mashalAs 时前面加上Out。
阅读全文
0 0
- C#与C++回调交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- unity 中 c# 与 object-c 交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C/C++的交互
- C#与C++/CLI的交互的一个细节
- 枚举类样例Java
- Android音乐播放模式切换-外放、听筒、耳机
- DataMasker数据脱敏平台
- Unity 5中如何控制检视面板上的属性是否显示
- POJ 1328 Radar Installation(贪心——最少区间选点覆盖)
- C#与C++回调交互
- android官方下拉刷新控件SwipeRefreshLayout的使用
- myeclipse中将java程序打包成可执行jar包
- spring-boot单元测试对weblistener的加载测试
- 【推荐】微服务大型分布式企业框架 Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis
- 解决装了Ubuntu耳机没有声音的问题(外放有声音)
- eclipse
- 阿里巴巴CTO行癫:阿里双11是世界互联网技术的超级工程
- task_delay