摘要
最近3天忙的一个项目,要死了。有个 C++ 写的 SDK dll,需要写成 C# 的接口提供给其他人,项目需要就要死人啊 T_T。接下来就介绍这个项目上使用的东西,下面有说不对的,请大家见谅,谢谢~~~
文章目录
目录
1. 非托管调用
这个方法我没有使用,不过各位可以参考 在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解)
2. 创建工程,VS2017
-
创建 C++ dll 工程
-
创建 C++ dll 测试工程
-
创建 C++ dll 中间件工程
-
创建 C# 工程
3. C++ 的接口 & 实现
-
C++ 的接口,很简单,没什么好说的,直接上代码
-
在工程属性中添加 CPLUSDLL_EXPORTS 宏,如果按照上面的操作进行创建工程,CPLUSDLL_EXPORTS 宏是已经添加到工程中的
-
ENGINE_EXPORTS __declspec(dllexport) 是用来 C 中导出的
-
destory 接口,我是直接把 this delete 掉了,所以不要在外面进行 delete engine 的操作,直接调用destory 就好了
#pragma once
#ifdef CPLUSDLL_EXPORTS
#define ENGINE_EXPORTS __declspec(dllexport)
#else
#define ENGINE_EXPORTS __declspec(dllimport)
#endif
namespace DllEngine {
#define DEVICE_NAME_MAX 32
#define DEVICE_COUNT_MAX 4
enum DeviceType {
QQ_DEVICE,
WEIXIN_DEVICE
};
struct Device {
char _pName[DEVICE_NAME_MAX];
};
struct DeviceList {
int _iCount;
Device _oDeviceList[DEVICE_COUNT_MAX];
};
struct Event {
char _pMessgae[DEVICE_NAME_MAX];
DeviceType _iType;
};
class IEventHandler
{
public:
virtual bool onNotify(Event* event, const char* message) = 0;
};
class IDeviceManger {
public:
virtual int GetDevice(DeviceList& deviceList) = 0;
};
class IEngine
{
public:
virtual IDeviceManger* GetDeviceManager() = 0;
virtual void SetHandle(IEventHandler* h) = 0;
virtual void Destory() = 0;
};
};
#if __cplusplus
extern "C" {
#endif
ENGINE_EXPORTS DllEngine::IEngine* CreateEngine();
#if __cplusplus
}
#endif
#include "stdafx.h"
#include "Engine.h"
namespace DllEngine {
class DeviceManger : public IDeviceManger {
public:
DeviceManger() {}
~DeviceManger() {}
int GetDevice(DeviceList& deviceList) {
deviceList._iCount = 3;
char name[DEVICE_NAME_MAX];
for (int i = 0; i < deviceList._iCount; i++) {
memset(name, 0, DEVICE_NAME_MAX);
memset(deviceList._oDeviceList[i]._pName, 0, DEVICE_NAME_MAX);
sprintf_s(name, DEVICE_NAME_MAX, "device list [%d]", i);
memcpy(deviceList._oDeviceList[i]._pName, name, DEVICE_NAME_MAX);
}
return deviceList._iCount;
}
};
class Engine : public IEngine
{
public:
Engine() {}
~Engine() {}
IDeviceManger* GetDeviceManager() {
if (_pDeviceManger == nullptr)
_pDeviceManger = new DeviceManger();
return _pDeviceManger;
}
void SetHandle(IEventHandler* h) {
_pEventHandle = h;
Event e;
e._iType = QQ_DEVICE;
memset(e._pMessgae, 0, DEVICE_NAME_MAX);
memcpy(e._pMessgae, "This is test", 12);
_pEventHandle->onNotify(&e, "Engine hello!!");
}
void Destory() {
if (_pDeviceManger)
delete _pDeviceManger;
_pDeviceManger = nullptr;
delete this;
}
private:
IEventHandler* _pEventHandle;
IDeviceManger* _pDeviceManger;
};
}
ENGINE_EXPORTS DllEngine::IEngine* CreateEngine() {
return new DllEngine::Engine();
}
4. C++ dll 测试工程
这个工程是测试 C++ 的接口是否可用,代码简单,就直接上了
#include "pch.h"
#include <iostream>
#include "../../dll/CplusDll/Engine.h"
class EventHandler : public DllEngine::IEventHandler {
public:
EventHandler() {}
~EventHandler() {}
bool onNotify(DllEngine::Event* event, const char* message) {
std::cout << "onNotify, Event._iType = " << event->_iType << std::endl;
std::cout << "onNotify, Event._pMessgae" << event->_pMessgae << std::endl;
st