C#调用C++ DLL时遇到的问题 C++定义了一个回调函数集
C#调用DLL时如何实现这个回调函数集 用接口和抽象类都试了都无法完成 请达人赐教
回调函数集
class IHikClientAdviseSink
{
public:
/******************************************************************
在Setup时被调用,获取总的播放长度.nLength为总的播放长度,以1/64秒为单位
*/
virtual int OnPosLength( unsigned long nLength ) = 0; /******************************************************************
在Setup后被调用,表示URL已经被成功打开,sucess为1表示成功,0表示失败
*/
virtual int OnPresentationOpened(int success) = 0; /************************************************************************
在Player被停止销毁后调用
*/
virtual int OnPresentationClosed() = 0; /************************************************************************
未使用
*/
virtual int OnPreSeek( unsigned long uOldTime, unsigned long uNewTime ) = 0; /************************************************************************
未使用
*/
virtual int OnPostSeek( unsigned long uOldTime, unsigned long uNewTime ) = 0; /************************************************************************
未使用
*/
virtual int OnStop() = 0; /************************************************************************
在Pause时被调用,uTime目前都是0
*/
virtual int OnPause( unsigned long uTime ) = 0; /************************************************************************
在开始播放时调用,uTime目前都是0
*/
virtual int OnBegin( unsigned long uTime ) = 0; /************************************************************************
在随机播放时调用,uTime目前都是0
*/
virtual int OnRandomBegin( unsigned long uTime ) = 0; /************************************************************************
在Setup前调用,pszHost表示正在连接的服务器
*/
virtual int OnContacting( const char* pszHost ) = 0;
/************************************************************************
在服务器端返回出错信息是调用, pError中为出错信息内容
*/
virtual int OnPutErrorMsg( const char* pError ) = 0;
/************************************************************************
未使用
*/
virtual int OnBuffering( unsigned int uFlag, unsigned short uPercentComplete ) = 0; virtual int OnChangeRate(int flag)=0; virtual int OnDisconnect()=0;
};
------------------------------------------------------------------------------------------------------
class CclientTestDlg : public CDialog, public IHikClientAdviseSink
{
// 构造
public:
CclientTestDlg(CWnd* pParent = NULL); // 标准构造函数
virtual int OnPosLength(unsigned long nLength );
virtual int OnPresentationOpened(int success);//int totaltime
virtual int OnPresentationClosed();
virtual int OnPreSeek( unsigned long uOldTime, unsigned long uNewTime );
virtual int OnPostSeek( unsigned long uOldTime, unsigned long uNewTime );
virtual int OnStop();
virtual int OnPause( unsigned long uTime );
virtual int OnBegin( unsigned long uTime );
virtual int OnRandomBegin( unsigned long uTime );
virtual int OnContacting( const char* pszHost );
virtual int OnBuffering( unsigned int uFlag, unsigned short uPercentComplete );
virtual int OnPutErrorMsg( const char* pError );
virtual int OnChangeRate(int flag);
virtual int OnDisconnect();
------------------------------------------------------------------------------------------------------
API:CLIENT_API HSESSION __stdcall HIKS_CreatePlayer(IHikClientAdviseSink* pSink, void* pWndSiteHandle, pDataRec pRecFunc, pMsgBack pMsgFunc=0,int TransMethod=0);//创建Player
C#调用DLL时如何实现这个回调函数集 用接口和抽象类都试了都无法完成 请达人赐教
回调函数集
class IHikClientAdviseSink
{
public:
/******************************************************************
在Setup时被调用,获取总的播放长度.nLength为总的播放长度,以1/64秒为单位
*/
virtual int OnPosLength( unsigned long nLength ) = 0; /******************************************************************
在Setup后被调用,表示URL已经被成功打开,sucess为1表示成功,0表示失败
*/
virtual int OnPresentationOpened(int success) = 0; /************************************************************************
在Player被停止销毁后调用
*/
virtual int OnPresentationClosed() = 0; /************************************************************************
未使用
*/
virtual int OnPreSeek( unsigned long uOldTime, unsigned long uNewTime ) = 0; /************************************************************************
未使用
*/
virtual int OnPostSeek( unsigned long uOldTime, unsigned long uNewTime ) = 0; /************************************************************************
未使用
*/
virtual int OnStop() = 0; /************************************************************************
在Pause时被调用,uTime目前都是0
*/
virtual int OnPause( unsigned long uTime ) = 0; /************************************************************************
在开始播放时调用,uTime目前都是0
*/
virtual int OnBegin( unsigned long uTime ) = 0; /************************************************************************
在随机播放时调用,uTime目前都是0
*/
virtual int OnRandomBegin( unsigned long uTime ) = 0; /************************************************************************
在Setup前调用,pszHost表示正在连接的服务器
*/
virtual int OnContacting( const char* pszHost ) = 0;
/************************************************************************
在服务器端返回出错信息是调用, pError中为出错信息内容
*/
virtual int OnPutErrorMsg( const char* pError ) = 0;
/************************************************************************
未使用
*/
virtual int OnBuffering( unsigned int uFlag, unsigned short uPercentComplete ) = 0; virtual int OnChangeRate(int flag)=0; virtual int OnDisconnect()=0;
};
------------------------------------------------------------------------------------------------------
class CclientTestDlg : public CDialog, public IHikClientAdviseSink
{
// 构造
public:
CclientTestDlg(CWnd* pParent = NULL); // 标准构造函数
virtual int OnPosLength(unsigned long nLength );
virtual int OnPresentationOpened(int success);//int totaltime
virtual int OnPresentationClosed();
virtual int OnPreSeek( unsigned long uOldTime, unsigned long uNewTime );
virtual int OnPostSeek( unsigned long uOldTime, unsigned long uNewTime );
virtual int OnStop();
virtual int OnPause( unsigned long uTime );
virtual int OnBegin( unsigned long uTime );
virtual int OnRandomBegin( unsigned long uTime );
virtual int OnContacting( const char* pszHost );
virtual int OnBuffering( unsigned int uFlag, unsigned short uPercentComplete );
virtual int OnPutErrorMsg( const char* pError );
virtual int OnChangeRate(int flag);
virtual int OnDisconnect();
------------------------------------------------------------------------------------------------------
API:CLIENT_API HSESSION __stdcall HIKS_CreatePlayer(IHikClientAdviseSink* pSink, void* pWndSiteHandle, pDataRec pRecFunc, pMsgBack pMsgFunc=0,int TransMethod=0);//创建Player
而你的类IHikClientAdviseSink有只包含函数。要知道Platform对类(结构)的支持只是Marshaling Data。C#端肯定是无法知道这些函数的。因此估计你只能将回调函数拿出到全局范围内。HIKS_CreatePlayer的参数接受这些回调函数。int OnPosLength( unsigned long nLength );
typedef int(*OnPosLength)(unsigned long nLength ); CLIENT_API HSESSION __stdcall HIKS_CreatePlayer(OnPosLength on****, ...)
这样在C#端可以定义callback供C#端调用。
参见:
using System;
using System.Runtime.InteropServices;public delegate bool CallBack(int hwnd, int lParam);public class EnumReportApp { [DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y); public static void Main()
{
CallBack myCallBack = new CallBack(EnumReportApp.Report);
EnumWindows(myCallBack, 0);
} public static bool Report(int hwnd, int lParam) {
Console.Write("Window handle is ");
Console.WriteLine(hwnd);
return true;
}
}
QueryInterface()
AddRef()
Release()
OnPosLength()
OnPresentationOpened()
...2. On the C++ side, we let IHikClientAdviseSink derive from IUnknown so they will be binary compatible.
3. Use PreserveSig to prevent CLR from striping/adding HRESULT as error code.
4. COM call convention is stdcall.
5. Here is an example:
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;namespace TestMyDll
{
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] //<----1
interface IHikClientAdviseSink
{
[PreserveSig] //<----3
int OnPosLength( uint nLength ); [PreserveSig]
int OnPresentationOpened(int success); [PreserveSig]
int OnPresentationClosed();
} class MyImplementation : IHikClientAdviseSink
{
public int OnPosLength(uint nLength)
{
Console.WriteLine("Managed OnPosLength:" + nLength);
return 11;
} public int OnPresentationOpened(int success)
{
Console.WriteLine("Managed OnPresentationOpened:" + success);
return 22;
} public int OnPresentationClosed()
{
Console.WriteLine("Managed OnPresentationClosed");
return 33;
}
} class Program
{
static MyImplementation myImplementation = new MyImplementation();
static void Main()
{
int i = HIKS_CreatePlayer(myImplementation);
Console.ReadLine();
}
[DllImport("MyDll.dll")]
extern static int HIKS_CreatePlayer(IHikClientAdviseSink pSink);
}
}// MyDll.cpp
//
#include <windows.h>
#include <atlbase.h>class IHikClientAdviseSink : IUnknown //<----2
{
public:
virtual int __stdcall OnPosLength( unsigned long nLength ) = 0; //<----4
virtual int __stdcall OnPresentationOpened(int success) = 0;
virtual int __stdcall OnPresentationClosed() = 0;
//....
};extern "C"
{
__declspec(dllexport) int __stdcall HIKS_CreatePlayer(IHikClientAdviseSink* pSink)
{
pSink->OnPosLength( 3 );
pSink->OnPresentationOpened( 6 );
pSink->OnPresentationClosed();
return 1234;
}
}