当前位置: 首页 > news >正文

【C#|C++】C#调用C++导出的dll之非托管的方式

C#调用C++导出的dll之非托管的方式

  • 1、宏定义导出关键字
  • 2、定义导出的方法
  • 3、关于对接中的一些变量问题
  • 4、关于一些细节问题
  • 5、设置visual studio


1、宏定义导出关键字

#ifndef dll_import
#define dll_export __declspec(dllexport)
#else
#define dll_export __declspec(dllimport)
#endif

__declspec 是 Microsoft C++ 编译器特有的关键字,用来为变量、函数、类等添加 存储类属性 或 编译器指令,从而控制它们的行为或链接方式。我们上述的操作就是给它一个更显示的指令名称,方便我们去理解和使用。


2、定义导出的方法

我们在需要被导出的函数的声明前面加上dll_export:

'''demo.hpp'''
extern "C" dll_export int __stdcall Add(int a, int b);'''demo.cpp'''
dll_export int __stdcall Add(int a, int b)
{...
}

这里的__stdcall是一种调用的约定方式,这里我们指定了__stdcall的方式,因此在C#调用时,需要指定好__stdcall的方式:

[DllImport("demo.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int Add(int a, int b);

这里需要注意的是,如果使用的是P/Invoke的方式来对接,那么我们不能导出类,只能导出方法,如果我们写的是类,那么需要再封装一下,变成一个独立的方法给c#调用。(clr托管的方式,即可通过导出类的方式来给c#调用。)


3、关于对接中的一些变量问题

C#中的图像可以使用byte*,byte[] 来传,c++则用unsigned char* 来接。其中需要注意的是,接收byte*的数据时,我们需要在C++中手动进行对齐,我们可以计算step,计算方式如下:

int step = width * 3;
if(step % 4 != 0)
{step = ((width * 3) / 4 ) + 1) * 4;
}
cv::Mat src(height, width, CV_8UC3, ImgPtr, step);

这样构建出来的mat才是正常的mat。其中这里的 × 3指的是三通道,如果接收的单通道的图,那么 × 1即可。

c++给c#传字符串时,可以使用const char *,c#那边接收可以用IntPtr来接收,然后使用Marshal.PtrToStringAnsi 将其转成string。

4、关于一些细节问题

c++的接口如果要返回字符串的话,尽可能的返回char* 类型,而不是string类型,因为在返回string的时候,有可能会导致c#与c++的入参不一致而出现乱码入参(虽然不知道为什么会这样)。

尽可能的指定__stdcall或者常见的还有__cdecl,然后我们就可以在C#中声明调用的方法时指定好同样的调用约定。

如果我们在方法中用了new char创建的变量,一定要记得写一个接口单独释放char* 指针,这个方法将会在c#中获得string后调用。

5、设置visual studio

将.exe全部设置成.dll

http://www.lryc.cn/news/603500.html

相关文章:

  • 百度前端面试题目整理
  • 基于springboot/java/VUE的旅游管理系统/旅游网站的设计与实现
  • 算法提升之数论(矩阵+快速幂)
  • [2025CVPR-图象分类]ProAPO:视觉分类的渐进式自动提示优化
  • B 站搜一搜关键词优化:精准触达用户的流量密码
  • deepseek+飞书多维表格 打造小红书矩阵
  • 线程崩溃是否导致进程崩溃
  • 【CAN总线】STM32 的 CAN 总线通信开发笔记(基于 HAL)
  • 【开源项目】轻量加速利器 HubProxy 自建 Docker、GitHub 下载加速服务
  • 系统改造:一次系统领域拆分的实战复盘
  • 多态示例。
  • kotlin使用mybatis plus lambdaQuery报错
  • XtestRunner一个比较好用好看的生成测试报告的工具
  • 系统间复制文档
  • 论文阅读--射频电源在半导体领域的应用
  • React--》实现 PDF 文件的预览操作
  • 配置daemon.json使得 Docker 容器能够使用服务器GPU【验证成功】
  • VitePress学习笔记
  • 彻底清理ArcGIS 10.2残留的步骤
  • Windows使用Powershell自动安装SqlServer2025服务器与SSMS管理工具
  • Vue.js 完全指南:从入门到精通
  • getgff.py脚本-python006
  • openbmc 阈值sensor分析
  • 计算机视觉(CV方向)算法基础
  • SketchUp纹理贴图插件Architextures安装使用图文教程
  • Linux sshfs 安全挂载远程文件系统 命令详解
  • Angular面试题目和答案大全
  • AR辅助前端设计:虚实融合场景下的设备维修指引界面开发实践
  • Mac m系列芯片安装node14版本使用nvm + Rosetta 2
  • YotoR模型:Transformer与YOLO新结合,打造“又快又准”的目标检测模型