C#通过dll调用带参数的C++代码
创始人
2024-03-31 18:06:28
0

工作上用到一个包,是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合在一起,导致代码大段飘红。。。注释掉就好了。
这是我的问题=。=

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...