C# 访问C++的Dll的实现
来源:互联网 发布:百度云盘 for mac 编辑:程序博客网 时间:2024/05/18 01:34
在我们开放过程中,常常会遇到c++的dll,我们可以使用回调方法去访问,如果别人给的dll是导出的类,而且是虚类的方法传出信息,那么我们就可以从c++转成CLR的dll,然后转到C# 中。原理我就不说了,直接上代码吧!通过头文件,大家直接实现去!很方便哟!可是花了我好长时间才全部实现的。呵呵!
具体请看: c++的dll如下:
//=============================================================================
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 SHZDTRADELIB_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// SHZDTRADELIB_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
// 向少中 2013-06-07
//=============================================================================
#ifdef SHZDTRADELIB_EXPORTS
#define SHZDTRADELIB_API __declspec(dllexport)
#else
#define SHZDTRADELIB_API __declspec(dllimport)
#endif
#ifdef __cplusplus
//===================================================================================
// 对外导出的接口,先绑定,然后初始化,绑定的端口如果为0,表示只做客户端通信
// 如果不为0表示做服务器端,同时做客户端。
//===================================================================================
class IShZdTradeLibIn
{
public:
virtual void Release() = 0;
virtual int InitShZdServer()=0;//初始化服务器
virtual int RegisterFront(const char *pszFrontAddress,int portNum,const char* localAdress,int localPortNum)=0; //连接前置服务器
virtual int SendTradeInfo(int clientId,const char* tradeInfo)=0;//向交易服务器发送交易请求
virtual int BindListenIpPort(const char* lIpAdress,int port)=0; //绑定监听的Ip地址和端口
virtual int SendOneClientTradeInfo(int clientId,const char* tradeInfo)=0;//向一个客户端发送信息
virtual int SendAllClientTradeInfo(const char* tradeInfo)=0;//向所有客户端发送信息
virtual int LibStart()=0; //开始
};
//====================================================================================
// 导入到DLl内部的接口
//====================================================================================
class IShZdTradeLibOut
{
public:
virtual int OnNotifyLoggerInfo(const char* logInfo)=0; //记录logInfo
virtual int OnNotifyDisconnectedClient(int clientId,const char * errorInfo)=0;//客户端断开连接的返回信息
virtual int OnNotifyNewConnectionClient(int clientId)=0; //新的客户端连接进来
virtual int OnNotifyTradeInfo(int clientId,const char* tradeInfo)=0;//接收到客户端传来的信息
};
// 此类是从 ShZdTradeLib.dll 导出的
class SHZDTRADELIB_API CShZdTradeLib {
public:
};
//导出接口的实例
typedef IShZdTradeLibIn* ShZdTradeLibInHandle;
typedef IShZdTradeLibOut* ShZdTradeLibOutHandle;
#else
#endif
#ifdef __cplusplus
# define EXTERN_C extern "C"
#else
# define EXTERN_C
#endif
//===============================================
// 工厂方法建立ShZdTradeLibIn的实例
//================================================
EXTERN_C SHZDTRADELIB_API ShZdTradeLibInHandle
GetShZdTradeLib(void);
//================================================
// 向dll内部设置接口实例,外面实现这个实例
//================================================
EXTERN_C SHZDTRADELIB_API void
SetShZdMarketLib(ShZdTradeLibOutHandle OutHandle);
那么我们就可以这样写CLR的DLL,以方便C#使用:
#pragma once
using namespace System;
//using namespace std;
#include "../ShZdTradeLib/ShZdTradeLib/ShZdTradeLib.h"
//向CShap中传递信息的导出函数
#ifndef ShZdTradeCRLLib_H
#define ShZdTradeCRLLib_H
typedef void (__stdcall * Callback)(const char* text);
extern "C" __declspec(dllexport)
extern void __stdcall SetGlobalCallback(Callback handler);
typedef void (__stdcall * CallbackClient)(int client_id,const char* text);
extern "C" __declspec(dllexport)
extern void __stdcall SetGlobalCallbackClient(CallbackClient handler);
typedef void (__stdcall * CallbackNewConnection)(int client_id);
extern "C" __declspec(dllexport)
extern void __stdcall SetGlobalCallbackNewConnection(CallbackNewConnection handler);
#endif
Callback Handler = 0;
void __stdcall SetGlobalCallback(Callback handler)
{
Handler = handler;
};
CallbackClient ClientHandler=0;
void __stdcall SetGlobalCallbackClient(CallbackClient handler)
{
ClientHandler=handler;
};
CallbackNewConnection ClientNewHandler=0;
void __stdcall SetGlobalCallbackNewConnection(CallbackNewConnection handler)
{
ClientNewHandler=handler;
}
//===========================================================
// 接收c的dll的信息,并通过导出函数,向CShap传递信息
//===========================================================
public class ShZdTradeCRLLibOut:public IShZdTradeLibOut
{
public:
int OnNotifyTradeInfo(const char* tradeInfo); //接收交易的返回信息
int OnNotifyLoggerInfo(const char* logInfo); //记录logInfo
int OnNotifyDisconnectedClient(int clientId,const char * errorInfo);//客户端断开连接的返回信息
int OnNotifyNewConnectionClient(int clientId); //新的客户端连接进来
int OnNotifyTradeInfo(int clientId,const char* tradeInfo);//接收到客户端传来的信息
};
//===============================================================
// 向dell中写信息的对象
//===============================================================
public ref class ShZdTradeCRLLibIn
{
private:
IShZdTradeLibIn* myLibIn;
public :
/*
* 建立方法
*/
ShZdTradeCRLLibIn()
{
myLibIn=::GetShZdTradeLib();
::SetShZdMarketLib(new ShZdTradeCRLLibOut);
}
/*
* 析构方法
*/
~ShZdTradeCRLLibIn()
{
myLibIn->Release();
}
int CRLInitShZdServer()//初始化服务器
{
return myLibIn->InitShZdServer();
}
int CRLRegisterFront(const char* pszFrontAddress,int portNum,
const char* localAdress,int localPortNum)//连接前置服务器
{
return myLibIn->RegisterFront(pszFrontAddress,portNum,localAdress,localPortNum);
}
int CRLSendTradeInfo(int clientId,const char* tradeInfo)//向交易服务器发送交易请求
{
return myLibIn->SendTradeInfo(clientId,tradeInfo);
}
int CRLBindListenIpPort(const char* lIpAdress,int port) //绑定监听的Ip地址和端口
{
return myLibIn->BindListenIpPort(lIpAdress,port);
}
int CRLSendOneClientTradeInfo(int clientId,const char* tradeInfo)//向一个客户端发送信息
{
return myLibIn->SendOneClientTradeInfo(clientId,tradeInfo);
}
int CRLSendAllClientTradeInfo(const char* tradeInfo)//向所有客户端发送信息
{
return myLibIn->SendAllClientTradeInfo(tradeInfo);
}
int CRLLibStart() //开始
{
return myLibIn->LibStart();
}
};
CLR的DLL实现了,那么就可以写C#的Dll了,这样在工程中使用就非常方便:
C#的代码:
public class CSharpShZdTradeLibOut
{
//返回字符串的回调
[DllImport("ShZdTradeCRLLib.dll", EntryPoint = "SetGlobalCallback",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern void SetGlobalCallback(Callback cb);
private delegate void Callback(string text);
private Callback CallbackInstance;
//返回int ,string的回调
[DllImport("ShZdTradeCRLLib.dll", EntryPoint = "SetGlobalCallbackClient",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern void SetGlobalCallbackClient(CallbackClient cb);
private delegate void CallbackClient(int clientId, string text);
private CallbackClient CallbackClientInstance;
//返回Int的回调
[DllImport("ShZdTradeCRLLib.dll", EntryPoint = "SetGlobalCallbackClient",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern void SetGlobalCallbackNewConnection(CallbackNewConnection cb);
private delegate void CallbackNewConnection(int clientId);
private CallbackNewConnection CallbackNewConnectionInstance;
/// <summary>
/// 定义运行返回信息事件
/// </summary>
public event DllInfoEvent.DllInfoHandler InfoLogHandler;
/// <summary>
/// 定义接收信息的事件
/// </summary>
public event DllInfoEvent.DllInfoHandler InfoRecHandler;
/// <summary>
/// 定义新客户连接事件
/// </summary>
public event DllInfoEvent.DllInfoHandler ClientNewHandler;
public CSharpShZdTradeLibOut()
{
//运行log返回的回调
CallbackInstance = new Callback(Handler_GlobalCallback);
SetGlobalCallback(CallbackInstance);
//客户信息返回的回调、客户断开信息的返回
CallbackClientInstance = new CallbackClient(Handler_ClientInfoBack);
SetGlobalCallbackClient(CallbackClientInstance);
//服务器接受到客户连接的返回
CallbackNewConnectionInstance = new CallbackNewConnection(Handler_NewClientConnection);
SetGlobalCallbackNewConnection(CallbackNewConnectionInstance);
}
}
}
C#工程中就这样使用了:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private CSharpShZdTradeLibIn myLibIn;
private CSharpShZdTradeLibOut myLibOut;
private void button1_Click(object sender, EventArgs e)
{
myLibIn = new CSharpShZdTradeLibIn();
myLibOut = new CSharpShZdTradeLibOut();
myLibOut.InfoLogHandler += new DllInfoEvent.DllInfoHandler(getDllInfo);
myLibOut.InfoRecHandler += new DllInfoEvent.DllInfoHandler(getDllInfo);
myLibOut.ClientNewHandler += new DllInfoEvent.DllInfoHandler(getDllInfo);
myLibIn.CSharp_InitShZdServer();
myLibIn.CSharp_BindListenIp("", 0);
myLibIn.CSharp_LibStart();
}
public void getDllInfo(object sender, DllInfoEvent e)
{
DllInfo info=e.EventArg;
MessageBox.Show(info.infoContent);
}
}
注意各个工程中的引用,顺序!
大家觉得是不是很方便呀!
- C# 访问C++的Dll的实现
- C# 访问 C DLL
- C#调用C的DLL
- C#调用C++DLL的方法
- C#动态调用c++DLL的方法
- 编写C#调用的C++DLL
- 编写C#调用的C++DLL
- C#调用C++dll的类型转换
- c#调用C/C++生成的dll
- C#调用C++DLL的类型对应
- C#动态调用c++DLL的方法
- C#调用C、C++的DLL
- c#调用c的dll原理理解
- C# 调用C++或者C的DLL
- 编写C#调用的C++DLL
- C#调试C++DLL的总结
- JAVA调用C++/C#的DLL
- C#调用C++、Opencv的Dll
- Android开源项目(非组件)
- JAVA中获取当前系统时间
- asp.net中的泛型
- IOS UITableView NSIndexPath属性讲解
- 错误票据(蓝桥杯JavaB组预赛)
- C# 访问C++的Dll的实现
- 各类进度条(pregressBar)合集
- Multi-threaded (/MT) 和Multi-threaded DLL (/MD)的区别
- 简单记录SQL和Oracle中的递归查询
- 《Test-Driven development By Example》阅读(二)
- map<Strng map<string map>>类型的值获取
- 经纬度相关计算
- 多线程
- linux vi编辑常用命令-