不磨叽,直接上代码。
C++动态库中函数定义
#ifndef _AUDIOSYSSDK_H
#define _AUDIOSYSSDK_H
typedef void PlayResFunc(void *powner,int filestate, int playlen);
extern "C"
{
int _stdcall Audio_OpenChannel(char *pLocalAddr,PlayResFunc *pFun,void *powner);
int _stdcall Audio_CloseChannel(int idx);
}
在C#中的调用的代码
#warning 这个委托一定要标记为Cdecl
/*
这个委托一定要标记为[System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.Cdecl)],
* 否则在C#调用时在回调函数执行一次后会退出或会抛出异常Access violation
*/
/// Return Type: void
///powner: void*
///filestate: int
///playlen: int
[System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void PlayResFunc(System.IntPtr powner, int filestate, int playlen);
public class AudioSysSdkHelper
{
[System.Runtime.InteropServices.DllImportAttribute("AudioSysSDK.dll", EntryPoint = "Audio_OpenChannel", CallingConvention = CallingConvention.StdCall)]
public static extern int Audio_OpenChannel(string pLocalAddr,PlayResFunc pFun,System.IntPtr powner);
}
winform程序调用的代码
public PlayResFunc PlayResFuncObj = null;
private void button3_Audio_OpenChannel_Click(object sender, EventArgs e)
{
string pLocalAddr = "192.168.7.22";
PlayResFuncObj =PlayRes;
channelIndex = AudioSysSdkHelper.Audio_OpenChannel(pLocalAddr, PlayResFuncObj, IntPtr.Zero);
if (channelIndex >= 0)
{
SetTextShow(string.Format("打开通道成功,通道号{0}", channelIndex));
}
else
{
SetTextShow(string.Format("打开通道失败,返回值{0}", channelIndex));
}
}
public void PlayRes(IntPtr powner, int filestate, int playlen)
{
try
{
int groupid = (int)powner;
ePlayStatus state = (ePlayStatus)filestate;
switch (state)
{
case ePlayStatus.PS_PlayDone:
SetTextShow("播放完毕");
//System.Diagnostics.Trace.WriteLine("播放完毕");
break;
case ePlayStatus.PS_PlayPause:
SetTextShow("播放暂停");
//System.Diagnostics.Trace.WriteLine("播放暂停");
break;
case ePlayStatus.PS_PlayStatus:
SetTextShow(string.Format("播放了百分之{0}", playlen));
//System.Diagnostics.Trace.WriteLine(string.Format("播放了百分之{0}", playlen));
break;
}
}
catch(Exception ex)
{
throw ex;
}
}
这个问题耗了我一天半的时间,这里Mark一下,备忘。
C#调用C++动态库的坑还是很多的。童鞋们注意自身安全!