实现C++调用C#的动态库dll
在实际的项目过程中,有时会遇到在C++的项目中调用某个C#的dll来完成特定的某个功能,我们都知道,Native C++是没办法直接调用.NET平台的dll的。那有没有办法来做到这一点了?答案是肯定的。
我们以OMCS实时音视频框架为例,OMCS WinPC 版的SDK是C#开发的,有些使用C++ QT开发Windows应用的客户,想调用OMCS来进行语音视频会话或远程桌面等功能,那该怎么做了?
虽然,Native C++是调用不了C#的dll的,但是Managed C++(C++/CLI)可以调用C#的dll,所以,可以使用C++/CLI作为桥梁来将 Native C++ 和 C#连接起来。
(1)新建一个C++/CLI的库(比如名称为OmcsWrap),添加引用并调用OMCS.dll,使用Managed C++语法调用OMCS.dll中的组件,并暴露出标准的C/C++接口。
(2)编译C++/CLI库得到 OmcsWrap.dll 和 OmcsWrap.lib。该库的接口是符合C++规范的。
(3)在Native C++项目(如QT)中,链接 OmcsWrap.dll、OmcsWrap.lib即可。
一.C++/CLI调用OMCS示例:连接摄像头
如果了解OMCS的基本用法(不了解的可以查看:OMCS入门Demo:语音视频、电子白板、远程桌面 功能展现),那么下面的C++/CLI的调用代码就很容易理解了。
我们新建一个C++/CLI的控制台项目,来演示如何通过OMCS的摄像头连接器连接到任意一个在线用户的摄像头,拿到摄像头的视频图像Bitmap数据。
using namespace System;
using namespace System::Drawing;
using namespace OMCS::Passive;
using namespace OMCS::Passive::Video;ref class Tester
{
private:DynamicCameraConnector^ dynamicCameraConnector;int frameCount = 0;public:Tester(){IMultimediaManager^ mgr = MultimediaManagerFactory::GetSingleton();//登陆 aa09mgr->Initialize("aa09", "", "127.0.0.1", 9900);Console::WriteLine(L"登录OMCS服务器成功!");}void Start(){dynamicCameraConnector = gcnew DynamicCameraConnector();dynamicCameraConnector->NewFrameReceived += gcnew ESBasic::CbGeneric<array<unsigned char, 1>^>(this, &Tester::OnNewFrameReceived);dynamicCameraConnector->ConnectEnded += gcnew ESBasic::CbGeneric<OMCS::Passive::ConnectResult>(this, &Tester::OnConnectEnded);//连接自己的摄像头dynamicCameraConnector->BeginConnect(L"aa09");}//摄像头图像数据void OnNewFrameReceived(array<unsigned char, 1>^ rgb24){Bitmap^ bm = ESBasic::Helpers::ImageHelper::ConstructRGB24Bitmap(rgb24, dynamicCameraConnector->VideoSize.Width, dynamicCameraConnector->VideoSize.Height);++this->frameCount;Console::WriteLine(L"收到图像帧:" + this->frameCount.ToString("00000"));}//连接摄像头的结果void OnConnectEnded(OMCS::Passive::ConnectResult result){if (result == ConnectResult::Succeed) //连接成功{Console::WriteLine(L"连接摄像头成功!");}else{Console::WriteLine(L"连接摄像头失败!原因:" + result.ToString());}}void Stop(){if (this->dynamicCameraConnector != nullptr){if (this->dynamicCameraConnector->Connected){this->dynamicCameraConnector->Disconnect(); //断开到目标摄像头的连接Console::WriteLine(L"断开摄像头连接器!");}this->dynamicCameraConnector = nullptr;} }
};
(1)这里仅仅是将收到的摄像头视频图像帧的帧数打印出来,真实的使用场景中,可以将图像帧回调传给QT,QT就可以在UI控件上将图像渲染出来。这样就可以看到视频了。
(2)这里是以摄像头为例,桌面也是完全一样的模式,使用DynamicDesktopConnector。
(3)对于麦克风声音,则更简单一下,因为其不需要UI渲染,所以直接在C++/CLI中调用MicrophoneConnector就可以了。连接目标麦克风成功,本地电脑就会自动播放其声音。
启动OMCS服务端(可从文末下载)后,运行本文的控制台程序,运行效果如下截图所示:
这里只是简单的示意一下C++/CLI调用OMCS的方式,至于封装一个给Native C++来调用C++/CLI库,这个库要提供哪些API,则取决于具体的项目需求,这里就不举例了。
二. Demo 源码下载
1. C++/CLI调用OMCS Demo:CppCli-CallOMCS-Demo.rar
2. Demo 服务端+C#客户端:OMCS.Demos.Simplest.rar
3. Android 客户端:OMCS.AndroidDemo.rar
4. iOS 客户端:OMCS.IOSDemo.zip
5. Web 版:OMCS.WebDemo.rar
关于OMCS实时视频功能的demo介绍,请参见这里。
实现C++调用C#的动态库dll相关推荐
- C#总结:C#调用C++的动态库Dll遇到的问题[动态库调用/结构体指针调用/union共同体定义]
记录使用C#调用C++的生成的DLL手柄键盘驱动库包括****.sys(驱动文件)和****.dll(库文件)的全部问题. C#调用C++的库有两种:静态调用和动态调用 静态调用,使用.net 提供的 ...
- C# VC6调用VC6的动态库DLL
C# VC6调用VC6的动态库DLL 一 VC创建动态库 1. DLL的创建 启动VC6.0, 新建一个"Win32 Dynamic-Link Library"工程,选择" ...
- C#调用C/C++动态库dll异常:对 PInvoke 函数调用导致堆栈不对称问题
结论:如果你是用C#调用C的动态库,如果出现"对 PInvoke 函数调用导致堆栈不对称问题",建议优先调整CallingConvention的值,建议改为CallingConve ...
- C#调用C/C++动态库Dll时几个注意事项:PInvoke错误
经常需要封装一些C/C++函数放入动态库中给C#程序调用,通常情况下直接写成如下形式即可: C#封装调用: [DllImport("depressor.dll")] //错误调用方 ...
- C#.net调用动态库dll注意事项
C#.net调用动态库dll注意事项 本文主要描述作者在工作中所遇到技术难点及问题,最后提出相关的解决方案 场景 公司有个业务需求涉及到ID读卡器,构建成在ID卡读卡器一刷ID卡,系统就自动显示其ID ...
- c 调用c语言写的dll文件路径,手把手教你用C/C++语言创建及调试动态库DLL程序
引子 动态链接库DLL文件不仅可以实现代码.资源和数据的共享,同时也可以对源代码起保护作用,对于开发者来讲,DLL的生成及调试是程序员必须掌握的一种技术,下面通过一个具体的例子,演示使用C/C++语言 ...
- java调用C或者C++动态库dll
java调用C或者C++动态库dll,本文章使用的是IntelliJ IDEA Community Edition 2021.2.3版本测试的 1.新建项目 linjie.demo,添加类HelloL ...
- C# 调用其他的动态库开发应注意的问题
1.背景 程序开发语言可以说是五花八门,这就引出了一个新问题 ,不同语言开发的系统进行对接时相关调用的问题. 下面我主要说一下我自己在做接口开发时遇到的问题及解决方法仅供参考,我使用的C#开发进行对接 ...
- graalvm把java编译为c/c++能够使用的动态库(dll/so)
graalvm把java编译为c/c++能够使用的动态库(dll/so) 1.安装graalvm oracle官方企业版 github的openjdk版本 1.1 下载对应系统版本,配置环境变量 本人 ...
最新文章
- python用for循环一直出现最后一个值_python中for循环的list最后一个数据总会覆盖前面的数据...
- mysql 数据库系统开发_MySQL------数据库系统概述
- 转: Linux下使用java -jar运行可执行jar包的正确方式
- 【Spring】详解spring事务属性
- 移动端使用页尾文字使用绝对定位遇到input框会飘起来的处理方案
- cc穿盾并发脚本_敢不敢模拟超过 5 万的并发用户?
- 2017 开源软件排行_2017年政府和公民如何使用开源解决人类问题
- 白嫖5T空间Onedrive并搭建下载站
- JavaWeb开发——JSP技术
- 网站防止CC攻击的方法,CC攻击原理及防范方法
- android:persistent=true作用
- 网易云课堂Java应用基础:入门篇
- Android GoogleMap 接入
- Eclipse一直building workspace: invoking maven project builder卡主
- c语言中数组名和数组名取地址理解
- pyqt tablewidget 设置一行的背景_PyQt+moviepy音视频剪辑实战2:一个剪裁视频文件精华内容留存工具的实现...
- 计算机英语brain,人类大脑纪录片《脑力大挑战 Test Your Brain》全3季 英语中字 标清/1080P高清纪录片...
- python移动文件到另一个文件夹若有同名文件更改文件名_Python 创建、复制、移动、删除和重命名文件和文件夹...
- 行人检测-ccv计算机视觉库应用
- Qt 读取多行文本框中的内容