先总结一部分
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)
{
}
void OnReceiveData(int id, int size, IntPtr data)
{
if (id == 2001)
{
try
{
Hand_Info pointer = (Hand_Info)Marshal.PtrToStructure(data, typeof(Hand_Info));
GeeVisionData.Enqueue(pointer);
}
catch (Exception e)
{
Debug.Log(e.Message);
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct Hand_Info
{
public int Gesture_ID; //!< static gesture event ID
public int Gesturedy_ID; //!< dynamic gesture event ID
public int Obeject_ID;
public Vector3 Center3D;
public Vector2 Center2D;
}
}
[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。