最近在做基于腾讯im的客服系统,需要在c#中集成腾讯IM的sdk。
封装方法大体上都差不多,下面代码是封装了部分功能,image和文件的转换把std::string 转成了String ,应该转成Byte[]。
消息封装 ,不包括TIMMessage
#pragma once
#include "stdafx.h"
#include <string>
#include <msclr\marshal_cppstd.h>
#include <msclr\auto_gcroot.h>
#include <iostream>
#include "IMHelp.h"
#include "tim.h"
using namespace msclr::interop;
using namespace System;
using namespace msclr;
namespace IMHelp {
template <class T>
public ref class ClrTextElem :ClrElem<T> {
public:
ClrTextElem() {
m_Elem = new imcore::TIMTextElem();
}
ClrTextElem(imcore::TIMTextElem *textElem) {
m_Elem = textElem;
}
!ClrTextElem() //确定性释放
{
delete m_Elem;
}
~ClrTextElem() //非确定性释放
{
this->!ClrTextElem();
}
property String^ content
{
String^ get()
{
return marshal_as<String^>(m_Elem->content());
}
void set(String^ content)
{
m_Elem->set_content(marshal_as<std::string>(content->ToString()));
}
}
private:
imcore::TIMTextElem *m_Elem;
};
template <class T>
public ref class ClrImage:CallBackBase
{
public:
ClrImage(imcore::TIMImage* nimage)
{
m_image = nimage;
}
~ClrImage() {};
void GetImageFile(String^ filename, ClrSuccessCallback^ nUploadImageSucces,
ClrErrorCallback^ nUploadImageError) {
gcroot<IMHelp::CallBackBase ^> obj =this;
ClrValueCallBack callback = ClrValueCallBack(obj);
uploadImageSucces = nUploadImageSucces;
uploadImageError = nUploadImageError;
std::string fileName = marshal_as(std::string)(filename);
m_image->GetImageFile(fileName, callback)
}
String^ GetUrl() {
String^ url= marshal_as<String^>(m_image->GetUrl);
return url;
}
int GetSize() {
return m_image->GetSize();
}
int GetHeight() {
return m_image->GetHeight();
}
int GetWidth() {
return m_image->GetWidth();
}
TIMImageType GetType() {
return m_image->GetType();
}
void succes()override {
uploadImageSucces();
}
void error(int code, String ^desc) override {
uploadImageError(code, desc);
}
ClrSuccessCallback^ uploadImageSucces;
ClrErrorCallback^ uploadImageError;
private:
imcore::TIMImage* m_image;
};
template <class T>
public ref class ClrImageElem :ClrElem<T> {
public:
ClrImageElem() {
m_Elem = new imcore::TIMImageElem();
}
ClrImageElem(imcore::TIMImageElem* imageElem ) {
m_Elem = imageElem;
}
!ClrImageElem() //确定性释放
{
delete m_Elem;
}
~ClrImageElem() //非确定性释放
{
this->!ClrImageElem();
}
property String^ uuid{
String^ get()
{
String^ uuid_ = marshal_as<String^>(m_Elem->uuid);
return uuid_;
}
void set(String^ uuid)
{
m_Elem->uuid = marshal_as<std::string>(uuid->ToString());
}
}
property String^ path {
String^ get()
{
String^ path_ = marshal_as<String^>(m_Elem->path);
return path_;
}
void set(String^ path)
{
m_Elem->path = marshal_as<std::string>(path->ToString());
}
}
property int taskid {
int get()
{
int taskid_ = m_Elem->taskid;
return taskid_;
}
void set(int taskid)
{
m_Elem->taskid = taskid;
}
}
property TIM_IMAGE_COMPRESS_TYPE leval
{
TIM_IMAGE_COMPRESS_TYPE get()
{
TIM_IMAGE_COMPRESS_TYPE leval_ = marshal_as<String^>(m_Elem->leval);
return leval_;
}
void set(TIM_IMAGE_COMPRESS_TYPE leval)
{
m_Elem->leval = leval;
}
}
array<ClrImage^>^ GetImages() {
std::vector<imcore::TIMImage>images = m_Elem->GetImages();
array<ClrImage^>^ clrImages= gcnew array<ClrImage^>(images.size);
for (size_t i = 0; i < images.size; i++)
{
imcore::TIMImage* image = &images[i];
ClrImage^ clrImg = gcnew ClrImage(image);
clrImages[i] = clrImg;
}
return clrImages;
}
bool CancelUploading() {
return m_Elem->CancelUploading();
}
int GetImageUploadProgrss() {
return m_Elem->GetImageUploadProgrss();
}
int GetImageFormat() {
return m_Elem->GetImageFormat();
}
private:
imcore::TIMImageElem *m_Elem;
};
template <class T>
public ref class ClrSoundElem :ClrElem , CallBackBase {
public:
ClrSoundElem() {
m_Elem =new imcore::TIMSoundElem();
}
ClrSoundElem(imcore::TIMSoundElem * soundElem) {
m_Elem = soundElem;
}
void GetSound(ClrSuccessCallback^ nGetSoundSucces,
ClrErrorCallback^ nGetSoundError) {
getSoundSucces = nGetSoundSucces;
getSoundError = nGetSoundError;
gcroot<IMHelp::CallBackBase ^> obj = this;
ClrValueCallBack callback = ClrValueCallBack(obj);
m_Elem->GetSound(&callback);
}
property String^ uuid {
String^ get()
{
String^ uuid_ = marshal_as<String^>(m_Elem->uuid);
return uuid_;
}
void set(String^ uuid)
{
m_Elem->uuid = marshal_as<std::string>(uuid->ToString());
}
}
property String^ data {
void set(String^ data)
{
m_Elem->set_data ( marshal_as<std::string>(data->ToString()));
}
}
property int data_size {
int get()
{
return m_Elem->data_size();
}
}
property int duration {
int get()
{
return m_Elem->duration();
}
void set(int duration)
{
m_Elem->set_duration(duration);
}
}
property String^ path {
void set(String^ path)
{
m_Elem->set_path ( marshal_as<std::string>(path->ToString()));
}
}
property int taskid {
int get()
{
int taskid_ = m_Elem->task_id;
return taskid_;
}
void set(int taskid)
{
m_Elem->task_id = taskid;
}
}
property int business_id {
void set(int business_id)
{
m_Elem->set_business_id(business_id);
}
}
property int download_flag {
void set(int download_flag)
{
m_Elem->set_download_flag(download_flag);
}
}
property array<String^> ^urls {
void set(array<String^>^ urls)
{
std::vector<std::string> IMurls = std::vector<std::string>();
for (size_t i = 0; i < urls -> GetLength(1); i++)
{
IMurls[i] = marshal_as<std::string>(urls[i]->ToString());
}
m_Elem->set_urls(IMurls);
}
}
void succes()override {
getSoundSucces();
}
void error(int code, String ^desc) override {
getSoundError(code, desc);
}
ClrSuccessCallback^ getSoundSucces;
ClrErrorCallback^ getSoundError;
private:
imcore::TIMSoundElem *m_Elem;
};
template <class T>
public ref class ClrFileElem :ClrElem<T> {
public:
ClrFileElem() {
m_Elem =new imcore::TIMFileElem();
}
ClrFileElem(imcore::TIMFileElem fileElem)
{
m_Elem = fileElem;
}
void GetFile(ClrSuccessCallback^ nGetFileSucces,
ClrErrorCallback^ nGetFileError) {
gcroot<IMHelp::CallBackBase ^> obj = this;
ClrCallBack callback = ClrCallBack(obj);
getFileSucces = nUploadImageSucces;
getFileError = nUploadImageError;
m_Elem->GetFile( callback);
}
property String^ uuid {
String^ get()
{
String^ uuid_ = marshal_as<String^>(m_Elem->uuid);
return uuid_;
}
void set(String^ uuid)
{
m_Elem->uuid = marshal_as<std::string>(uuid->ToString());
}
}
property String^ data {
void set(String^ data)
{
m_Elem->set_data(marshal_as<std::string>(data->ToString()));
}
}
property int file_size {
int get()
{
return m_Elem->file_size();
}
}
property String^ set_file_name {
void set(String^ set_file_name)
{
m_Elem->set_file_name(marshal_as<std::string>(set_file_name->ToString()));
}
}
property String^ set_file_path {
void set(String^ set_file_path)
{
m_Elem->set_file_path(marshal_as<std::string>(set_file_path->ToString()));
}
}
property int taskid {
int get()
{
int taskid_ = m_Elem->task_id;
return taskid_;
}
void set(int taskid)
{
m_Elem->task_id = taskid;
}
}
property int business_id {
void set(int business_id)
{
m_Elem->set_business_id(business_id);
}
}
property int download_flag {
void set(int download_flag)
{
m_Elem->set_download_flag(download_flag);
}
}
property array<String^> ^urls {
void set(array<String^>^ urls)
{
std::vector<std::string> IMurls = std::vector<std::string>();
for (size_t i = 0; i < urls->GetLength(1); i++)
{
IMurls[i] = marshal_as<std::string>(urls[i]->ToString());
}
m_Elem->set_urls(IMurls);
}
}
void GetFileByUUID(String^ uuid,int business_id, ClrSuccessCallback^ nGetFileSucces,
ClrErrorCallback^ nGetFileError) {
gcroot<IMHelp::CallBackBase ^> obj = this;
ClrCallBack callback = ClrCallBack(obj);
getFileSucces = nUploadImageSucces;
getFileError = nUploadImageError;
m_Elem->GetFileByUUID(marshal_as<std::string>(uuid), business_id, callback);
}
void succes()override {
getFileSucces();
}
void error(int code, String ^desc) override {
getFileError(code, desc);
}
ClrSuccessCallback^ getFileSucces;
ClrErrorCallback^ getFileError;
private:
imcore::TIMFileElem m_Elem;
};
template <class T>
public ref class ClrCustomElem :ClrElem<T> {
public:
ClrCustomElem() {
m_Elem = new imcore::TIMCustomElem();
}
ClrCustomElem(imcore::TIMCustomElem customRlem) {
m_Elem = customRlem;
}
property String^ data {
void set(String^ data)
{
m_Elem->set_data(marshal_as<std::string>(data->ToString()));
}
String^ get() {
String^ cData = marshal_as<String ^>(m_Elem->data());
return cData;
}
}
property String^ desc {
void set(String^ desc)
{
m_Elem->set_desc(marshal_as<std::string>(desc->ToString()));
}
String^ get() {
String^ desc = marshal_as<String ^>(m_Elem->desc());
return desc;
}
}
property String^ ext {
void set(String^ ext)
{
m_Elem->set_ext(marshal_as<std::string>(ext->ToString()));
}
String^ get() {
String^ _ext = marshal_as<String ^>(m_Elem->ext());
return _ext;
}
}
property String^ sound {
void set(String^ sound)
{
m_Elem->set_sound(marshal_as<std::string>(sound->ToString()));
}
String^ get() {
String^ _sound = marshal_as<String ^>(m_Elem->sound());
return _sound;
}
}
private:
imcore::TIMCustomElem m_Elem;
};
template <class T>
public ref class ClrLocationElem :ClrElem<T> {
public:
ClrLocationElem() {
m_Elem = new imcore::TIMLocationElem();
}
ClrLocationElem(imcore::TIMLocationElem locationElem) {
m_Elem = locationElem;
}
property String^ desc {
void set(String^ desc)
{
m_Elem->set_desc(marshal_as<std::string>(desc->ToString()));
}
String^ get() {
String^ desc = marshal_as<String ^>(m_Elem->desc());
return desc;
}
}
property String^ longitude {
void set(String^ longitude)
{
m_Elem->set_longitude(marshal_as<std::string>(longitude->ToString()));
}
String^ get() {
String^ longitude = marshal_as<String ^>(m_Elem->longitude());
return longitude;
}
}
property String^ latitude {
void set(String^ latitude)
{
m_Elem->set_latitude(marshal_as<std::string>(latitude->ToString()));
}
String^ get() {
String^ latitude = marshal_as<String ^>(m_Elem->latitude());
return latitude;
}
}
private:
imcore::TIMLocationElem m_Elem;
};
template <class T>
public ref class ClrFaceElem :ClrElem<T> {
public:
ClrFaceElem() {
m_Elem = new imcore::TIMFaceElem();
}
ClrFaceElem(imcore::TIMFaceElem faceElem) {
m_Elem = faceElem;
}
property String^ data {
void set(String^ data)
{
m_Elem->set_data(marshal_as<std::string>(data->ToString()));
}
String^ get() {
String^ cData = marshal_as<String ^>(m_Elem->data());
return cData;
}
}
property int data {
void set(int data)
{
m_Elem->set_index(data);
}
int get() {
int cData = m_Elem->index();
return cData;
}
}
private:
imcore::TIMFaceElem m_Elem;
};
template <class T>
public ref class ClrElem {
public:
ClrElem() {
}
ClrElem(imcore::TIMElem *elem) {
m_Elem = elem;
}
void set_type(TIMElemType type) {
m_Elem->set_type(type);
}
void Release() {
m_Elem->Release();
}
ClrTextElem^ GetTextElem() {
imcore::TIMTextElem *texteLem = m_Elem->GetTextElem();
ClrTextElem^ textElem = gcnew IMHelp::ClrTextElem(texteLem);
return textElem;
}
ClrImageElem^ GetImageElem() {
imcore::TIMImageElem *imageeLem = m_Elem->GetTextElem();
ClrTextElem^ imageELem = gcnew IMHelp::ClrImageElem(imageeLem);
return imageRLem;
}
ClrSoundElem^ GetSoundElem() {
imcore::TIMSoundElem *eLem = m_Elem->GetTextElem();
ClrSoundElem^ soundElem = gcnew IMHelp::ClrSoundElem(eLem);
return soundElem;
}
ClrFileElem^ GetFileElem() {
imcore::TIMFileElem *eLem = m_Elem->GetTextElem();
ClrFileElem^ fileElem = gcnew IMHelp::ClrFileElem(eLem);
return fileElem;
}
ClrCustomElem^ GetCustomElem() {
imcore::TIMCustomElem *eLem = m_Elem->GetTextElem();
ClrCustomElem^ customElem = gcnew IMHelp::ClrCustomElem(eLem);
return customElem;
}
ClrLocationElem^ GetLocationElem() {
imcore::TIMLocationElem *eLem = m_Elem->GetTextElem();
ClrLocationElem^ locationElem = gcnew IMHelp::ClrLocationElem(eLem);
return locationElem;
}
ClrFaceElem^ GetFaceElem() {
imcore::TIMFaceElem *eLem = m_Elem->GetTextElem();
ClrFaceElem^ faceElem = gcnew IMHelp::ClrFaceElem(eLem);
return faceElem;
}
imcore::TIMElem *m_Elem;
};
}
部分接口及部分回调:
头文件
using namespace System;
namespace IMHelp {
public delegate void ClrSuccessCallback();
public delegate void ClrErrorCallback(int code ,String^ desc);
public delegate void LoginOutSuccessCallback();
public delegate void LoginOutErrorCallback();
public delegate void ConnCallback();
public delegate void DisConnCallback();
public delegate void MassageRecv();
public interface class CallBackBase {
public:
virtual void error(int code, String ^desc);
virtual void succes();
};
public ref class Wrapper:CallBackBase
{
private:
Wrapper(const Wrapper%) { throw gcnew System::InvalidOperationException("singleton cannot be copy-constructed"); }
static Wrapper m_instance;
public:
static property Wrapper^ Instance { Wrapper^ get() { return %m_instance; } }
Wrapper();
Wrapper(ClrSuccessCallback^ nLoginSucces,
ClrErrorCallback^ nLoginError,
LoginOutSuccessCallback^ nLoginOutSuccessCallback,
LoginOutErrorCallback^ nLoginOutErrorCallback,
ConnCallback^ nConnCallback,
DisConnCallback^ nDisConnCallback,
MassageRecv^ nMassageRecv);
void login();
void init();
void SendMsg();
void TIMGetConversation();
void TIMLogout();
void TIMUnInit();
void succes() override{
loginSucces();
}
void error(int code, String ^desc) override {
loginError(code, desc);
}
ClrSuccessCallback^ loginSucces;
ClrErrorCallback^ loginError;
LoginOutSuccessCallback^ loginOutSuccessCallback;
LoginOutErrorCallback^ loginOutErrorCallback;
ConnCallback^ tIMConnCallback;
DisConnCallback^ tIMDisConnCallback;
MassageRecv^ tIMMassageRecv;
};
public class ClrCallBack :public imcore::TIMCallBack
{
public:
ClrCallBack();
ClrCallBack(gcroot<IMHelp::CallBackBase ^> sendObject) {
m_sendObject = sendObject;
}
~ClrCallBack();
void OnSuccess();
void OnError(int code, const std::string &desc);
private :
gcroot<IMHelp::CallBackBase ^> m_sendObject;
};
template <class T>
public class ClrValueCallBack :public imcore::TIMValueCallBack<T>
{
public:
ClrValueCallBack() {
}
ClrValueCallBack(gcroot<IMHelp::CallBackBase ^> sendObject) {
m_sendObject = sendObject;
}
~ClrValueCallBack() {}
void OnSuccess(T value) {
}
void OnError(int code, const std::string &desc) {
}
private:
gcroot<IMHelp::CallBackBase ^> m_sendObject;
};
}
cpp
// 这是主 DLL 文件。
#include "stdafx.h"
#include <msclr\marshal_cppstd.h>
#include <msclr\auto_gcroot.h>
#include "tim.h"
#include "IMHelp.h"
using namespace imcore;
using namespace msclr;
private class MessageCallBack:public imcore::TIMMessageCallBack
{
public:
MessageCallBack();
~MessageCallBack();
void OnNewMessage(const std::vector<TIMMessage> &msgs);
};
MessageCallBack::MessageCallBack()
{
}
MessageCallBack::~MessageCallBack()
{
}
void MessageCallBack::OnNewMessage(const std::vector<TIMMessage>& msgs)
{
array<int >^ cMegs=gcnew array<int>(msgs.size());
for (size_t i = 0; i < msgs.size(); i++)
{
cMegs[i]=i;
}
auto_gcroot<IMHelp::Wrapper^> s(IMHelp::Wrapper::Instance);
s->tIMMassageRecv();
}
private class ConnCallBack:public imcore::TIMConnCallBack
{
public:
ConnCallBack();
~ConnCallBack();
void OnConnected();
void OnDisconnected();
};
ConnCallBack::ConnCallBack()
{
}
ConnCallBack::~ConnCallBack()
{
}
void ConnCallBack::OnConnected()
{
}
void ConnCallBack::OnDisconnected()
{
}
IMHelp::Wrapper::Wrapper(ClrSuccessCallback^ nLoginSucces,
ClrErrorCallback^ nLoginError,
LoginOutSuccessCallback^ nLoginOutSuccessCallback,
LoginOutErrorCallback^ nLoginOutErrorCallback,
ConnCallback^ nConnCallback,
DisConnCallback^ nDisConnCallback,
MassageRecv^ nMassageRecv)
{
loginSucces = nLoginSucces;
loginError = nLoginError;
}
IMHelp::Wrapper::Wrapper()
{
}
void IMHelp::Wrapper::login()
{
imcore::TIMManager timManager = imcore::TIMManager::get();
int sdk_app_id = 1104620500;
TIMUserInfo user;
user.account_type = "107";
user.app_id_at_3rd = "1104620500";
user.identifier = "c9_2";
const char* user_sig = "pass_word";
gcroot<IMHelp::CallBackBase ^> obj = this;
ClrCallBack callback = ClrCallBack(obj);
TIMCallBack nCallback = callback;
timManager.Login(sdk_app_id, &user, user_sig, &nCallback);
}
void IMHelp::Wrapper::init()
{
imcore::TIMManager timManager = imcore::TIMManager::get();
String^ managed = "./";
MessageCallBack messageCallBack= MessageCallBack();
TIMMessageCallBack& nMessageCallback = messageCallBack;
ConnCallBack connCallBack = ConnCallBack();
TIMConnCallBack& nConnCallBack = connCallBack;
timManager.set_mode(1);
timManager.set_path(msclr::interop::marshal_as<std::string>(managed));
timManager.set_log_level(TIMLogLevel::kLogDebug);
timManager.SetMessageCallBack(&nMessageCallback);
timManager.SetConnCallBack(&nConnCallBack);
timManager.Init();
}
void IMHelp::Wrapper::
TIMLogout()
{
imcore::TIMManager timManager = imcore::TIMManager::get();
ClrCallBack callback = ClrCallBack();
TIMCallBack nCallback =callback;
timManager.Logout(&callback);
}
void IMHelp::Wrapper::TIMUnInit()
{
imcore::TIMManager timManager = imcore::TIMManager::get();
timManager.Uninit();
}
void IMHelp::ClrCallBack::OnSuccess() {
m_sendObject->succes();
}
void IMHelp::ClrCallBack::OnError(int code, const std::string &desc) {
m_sendObject->error(code, gcnew String(desc.c_str()));
}
IMHelp::ClrCallBack::ClrCallBack()
{
}
IMHelp::ClrCallBack::~ClrCallBack()
{
}