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

C#通过dll调用带参数的C++代码

工作上用到一个包,是c++写的,想在c#项目里调用,折腾了好久才终于成功了。踩坑踩了一天,我也是有毒。

环境:win10 + vs2022 + NETFramework4.7.2

制作dll

创建新项目-动态链接库
在这里插入图片描述
主要修改以下两个文件:pch.h和pch.cpp
在这里插入图片描述

修改pch.cpp

// pch.cpp: 与预编译标头对应的源文件
#include "pch.h"

//这里正常写c++代码,以下函数是我举例
char* getAlign(char* query, int queryLength, char* target, int targetLength) {...实现...}

修改pch.h

只有extern那行是我写的,其他是自动生成的。

#ifndef PCH_H
#define PCH_H

// 添加要在此处预编译的标头
#include "framework.h"

extern "C" _declspec(dllexport) char* getAlign(char* query, int queryLength, char* target, int targetLength);

#endif //PCH_H

检查一下项目属性

在这里插入图片描述
ok了之后点击生成,输出中有下面这样的文字:

1>项目名.vcxproj -> C:\我的路径\项目名\x64\Debug\项目名.dll
========== “全部重新生成”: 1 成功,0 失败,0已跳过 ==========

c#中调用

检查项目属性

在这里插入图片描述
保持跟dll的一致。

调用

这里的路径当然可以改,因为我在调试,所以偷懒了。最终确定的dll应该加到c#的引用里去。

[DllImport("C:\我的路径\项目名\x64\Debug\项目名.dll")]
public static extern IntPtr getAlign(IntPtr query, int queryLength, IntPtr target, int targetLength);
...
private void drawSeqCompCanvas() {
	string query = "hello";
	string target = "world";
	IntPtr p = getAlign(Marshal.StringToHGlobalAnsi(query), query.Length,
	Marshal.StringToHGlobalAnsi(target), target.Length);
	Console.WriteLine(Marshal.PtrToStringAnsi(p));
}

解释一下:c++中的char*,c#是用IntPtr来接收的,所以无论是参数还是返回值,c++中的char*,在c#中都要改成IntPtr。至于Marshal那两句,就是IntPtr和String的互相转换。

常见bug

LINK : fatal error LNK1104: 无法打开文件“XXX.dll”

在制作dll时可能会出现这个问题。基本是因为另一个程序在引用这个dll,只要找到占用者,关掉即可。

System.AccessViolationException

c#调用dll出这个问题,很可能是调用dll里函数时,类型错误。比如C/C++中的unsigned short并不对应于C#中的ushort类型,而是UInt16这个类型,以及int[]传入C/C++,要用int* 接收。
我这次打包的问题则是,最开始时getAlign()接受的是string参数,但c++和c#的string似乎不一样,改成char*和IntPtr,问题解决。
参考:https://blog.csdn.net/Mr_L_K/article/details/112800806

重载min

copy代码时没注意,头文件里有下面这种,我直接copy过去了。

static inline int min(const int x, const int y) {
    return x < y ? x : y;
}

本来在单独头文件+限定namespace,是没有问题的,但是跟cpp合在一起,导致代码大段飘红。。。注释掉就好了。
这是我的问题=。=

相关文章:

  • 【C++】一文带你吃透string的模拟实现 (万字详解)
  • 融合transformer和对抗学习的多变量时间序列异常检测算法TranAD论文和代码解读...
  • Hdfs梳理
  • 智能小车 - DRV8833电机驱动模块
  • Spring常用注解——@Autowired自动装配的作用和原理
  • 一些运维命令
  • 代码随想录动态规划——背包问题总结篇
  • web安全之信息收集
  • 基于FPGA的双目相机目标深度图像提取实现——详细版
  • 【饭谈】细嗦那些职场中喜欢用领导口气命令别人的同事
  • 10 通用同步异步收发器(USART)
  • AI绘图—对中文拟合度很高,值得一试
  • 【 C++11 】包装器
  • 【动手学深度学习PyTorch版】13 卷积层的填充和步幅
  • 第十三届蓝桥杯C++B组国赛H题——机房 (AC)
  • 2017前端实习生面试总结
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • django开发-定时任务的使用
  • Intervention/image 图片处理扩展包的安装和使用
  • JS学习笔记——闭包
  • JWT究竟是什么呢?
  • nodejs:开发并发布一个nodejs包
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 初探 Vue 生命周期和钩子函数
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端相关框架总和
  • 深入浏览器事件循环的本质
  • 使用parted解决大于2T的磁盘分区
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • ​力扣解法汇总946-验证栈序列
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #Z2294. 打印树的直径
  • (11)MSP430F5529 定时器B
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (TOJ2804)Even? Odd?
  • (zhuan) 一些RL的文献(及笔记)
  • (笔试题)分解质因式
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (转)【Hibernate总结系列】使用举例
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .net 后台导出excel ,word
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
  • /proc/vmstat 详解
  • @KafkaListener注解详解(一)| 常用参数详解
  • @Query中countQuery的介绍
  • @Service注解让spring找到你的Service bean
  • [ C++ ] STL_list 使用及其模拟实现
  • [2013AAA]On a fractional nonlinear hyperbolic equation arising from relative theory
  • [BZOJ2208][Jsoi2010]连通数
  • [Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)
  • [CentOs7]图形界面