首页 > 编程语言 >C# 封装 C++的dll

C# 封装 C++的dll

时间:2023-09-09 09:23:12浏览次数:45  
标签:调用 C# SGP CharSet C++ dll public

C# 的程序引用C++的dll时,首先要保证两者基于的平台一致,比如都是x64,或者都是x86的程序,否者两者之间不能直接调用,然后,要保证两者的数据类型可以相互识别,相互通用。在此重点介绍几个常用的数据转换。

  1. C++的char* 和 char[] 数组,对应到C#的string 类型
  2. C++的Handle 类型,一般是一个很大的整数,C#可以使用 IntPtr
  3. 对于指针类型的要使用ref
  4. C++中的结构体,可以在C#中声明同样名称的结构体,但是要进行一定的设置
    1. 使用StructLayout 特性设置结构体,当有char时,要设置 CharSet = CharSet.Ansi
    2. 使用string时,要使用 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)] 特性修饰,并分配与原c++中的char数组相同大小的内存
使用DllImportAttribute(string dllPath) 来构造C++的同名函数,此特性有几个常用字段
  • CharSet 指示如何向方法传送字符串参数,并控制名称重整
    • None 与 Ansi具有相同的行为
    • Ansi 以单字节的形式封装传送字符串
    • Auto针对操作系统自动封装字符串
    • Unicode 以双字节的形式封送字符串
  • CallingConvention 指示入口点的调用规则
    • Cdecl 调用方清理堆栈
    • StdCall 被调用方清理堆栈
    • ThisCall 第一个参数是this指针
    • Winapi 默认平台调用约定
  结构体与函数举例    结构体举例1:
C++结构体
struct SGP_ANALYTIC_TEMP
{
    int rule_id;     
    char rule_name[50];   
    float max_temp; 
}; 
 
C#对应的结构体声明
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SGP_ANALYTIC_TEMP
{
    public int rule_id = 0;    

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
    public string rule_name="123";   

    public float max_temp = 0;//最高温度值

}
结构体举例2:结构体中嵌套结构体,此时对于结构体数组,也要使用MarshalAs指定类型,并分配内存
C++结构体
struct SGP_GENERAL_INFO
{       
       int range_num;//测温范围数量
       
       SGP_RANGE range[3];//测温范围
       
       char vl_rtsp_url[50];//可见光主码流rtsp地址
};

C++ 函数类型 
int SGP_GetGeneralInfo(SGP_HANDLE handle, SGP_GENERAL_INFO *output);

C# 对应的结构体
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SGP_GENERAL_INFO
{

    
    public int range_num ;//测温范围数量
   
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
    public SGP_RANGE[] range;//测温范围

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
    public string vl_sub_rtsp_url;//可见光辅码流rtsp地址
}

C# 函数类型
[DllImport(sdkPath, EntryPoint = "SGP_GetGeneralInfo", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int SGP_GetGeneralInfo(IntPtr handle, ref SGP_GENERAL_INFO output);

 

遇到的问题 问题1 : 在引入DLL中的方法时,有时会出现以下错误报告:“在使用托管代码调用非托管代码时,发生“ 对 PInvoke 函数的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。 解决方法: 在DllImport时添加 CallingConvention = CallingConvention.Cdecl 即调用方清理堆栈,注意,当调用的C++dll还依赖其他dll时,需要把所调用的dll文件都放在一起,否则会抛出 System.DllNotFoundException的异常   问题2: 0   解决方法: 主要是由于Dll编译的平台和调用它的工程的平台不一致导致的,可都统一打到X64平台下编译  

 

 

 

 

 

 

 

 

标签:调用,C#,SGP,CharSet,C++,dll,public
From: https://www.cnblogs.com/liushuiruobing/p/17688908.html

相关文章

  • mysql 开启cdc归档日志
    1、介绍mysql开启归档只需要在mysql的 my.ini 中添加几个配置即可(适用版本如下:)2、说明如下:#配置二进制日志,下面的路径logs文件夹需要提前建好log-bin=E:/mariadb-10.4.20-winx64/logs/mysql-bin.log#设置最大存储空间max-binlog-size=50000M#指定服务idser......
  • C++系列三:QT-Quick
    目录前言:理论:案例:前言:其实和我接触过的Flutter,有异曲同工之处。记住F1,其实就ok了。参考链接:官方、教程1、教程2、教程3、教程3理论:案例://main.cpp:QQmlApplicationEngineengine;engine.load(QUrl(QStringLiteral("qrc:/qt/qml/qtquickapplication1/main.qml")));if(e......
  • pytest运行警告问题解决:DeprecationWarning: pkg_resources is deprecated as an API
    前言最近在运行pytest的时候,经常出现这个警告DeprecationWarning:pkg_resourcesisdeprecatedasanAPISeehttps://setuptools.pypa.io/en/latest/pkg_resources.htmlfrompkg_resourcesimportiter_entry_points从警告上看是方法被弃用,肯定是因为新版弃用了旧版的语法。......
  • 修改 node 默认的全局模块安装 global 路径和 cache 路径
    修改node默认的全局模块安装global路径和cache路径安装node后,全局模块的global路径和cache路径默认安装在C:\Users\{{账号}}\AppData\Roaming下,在这个目录下面会找到npm文件夹和npm_cache的文件夹。在其他的盘符建立node_global文件夹和node_cache文......
  • 浅聊一下SpringMVC的核心组件以及通过源码了解其执行流程
    浅聊一下SpringMVC的核心组件以及通过源码了解其执行流程MVC作为WEB项目开发的核心环节,正如三个单词的分解那样,Controller(控制器)将View(视图、用户客户端)与Model(javaBean:封装数据)分开构成了MVC,今天我们浅聊一下SpringMVC的相关组件以及通过源码了解器执行流程SpringMVC的核心组......
  • IDEFICS 简介: 最先进视觉语言模型的开源复现
    引言CodeLlama是为代码类任务而生的一组最先进的、开放的Llama2模型,我们很高兴能将其集成入HuggingFace生态系统!CodeLlama使用与Llama2相同的社区许可证,且可商用。今天,我们很高兴能发布HuggingFace对CodeLlama的全面支持,包括:Hub上的模型支持,包括模型......
  • Go - ERROR: # command-line-arguments undefined
    zzh@ZZHPC:/zdata/MyPrograms/Go/aaa/Ch05/05_04$gorunhttpd.go#command-line-arguments./httpd.go:15:9:undefined:DB./httpd.go:58:16:undefined:NewDBzzh@ZZHPC:/zdata/MyPrograms/Go/aaa/Ch05/05_04$gorun*.go2023/09/0823:29:15error:sql:unknowndriver......
  • oracle查看表锁以及对应语句
    setlinesize400pagesize999\rcolmachinefora20\rcolsql_idfora20\rcolprev_sql_idfora20\rcolobject_namefora20\rcolobject_typefora20\rcoloracle_usernamefora15\rSELECTs.inst_id,\rs.sql_id,\rs.prev_sql_id,\......
  • Proj CDeepFuzz Paper Reading: Metamorphic Testing of Deep Learning Compilers
    Abstract背景:CompilingDNNmodelsintohigh-efficiencyexecutablesisnoteasy:thecompilationprocedureofteninvolvesconvertinghigh-levelmodelspecificationsintoseveraldifferentintermediaterepresentations(IR),e.g.,graphIRandoperatorIR,an......
  • Nacos 配置中心:微服务架构的利器
    1.本次文章主要介绍如何使用Nacos作为项目的配置中心。研发环境如下:SpringCloud、SpringBoot和spring-cloud-alibaba本版如下spring-cloud:2021.0.6spring-cloud-alibaba:2021.0.5.0springBoot:2.7.142.为什么需要配置中心在微服务架构中,系统被拆分成多个小型、独立的服务,每个服......