C#通过dll调用带参数的C++代码传递字符串、返回int和int数组
2023/1/31 更新:传递int数组
以下是原文
工作上用到一个包,是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) {...实现...}
// 要求返回一个int
int getStartsCount() {...实现...}
// 要求返回一个int[]
void getStartLocations(int* N, const int count) {
for (int i = 0; i < count; i ) { ...对N[i]进行赋值... }
}
修改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);
extern "C" _declspec(dllexport) int getStartsCount();
extern "C" _declspec(dllexport) void getStartLocations(int* N, const int count);
#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);
[DllImport("C:\我的路径\项目名\x64\Debug\项目名.dll")]
public static extern int getStartsCount();
[DllImport("C:\我的路径\项目名\x64\Debug\项目名.dll")]
public static extern void getStartLocations([MarshalAs(UnmanagedType.LPArray,
SizeParamIndex = 1)] int[] Z, int count);
...
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));
int startCount = getStartsCount();
int[] starts = new int[startCount];
getStartLocations(starts, startCount);
}
解释一下:c 中的char*,c#是用IntPtr来接收的,所以无论是参数还是返回值,c 中的char*,在c#中都要改成IntPtr。至于Marshal那两句,就是IntPtr和String的互相转换。
对于int[],因为c 与c#不能传递数组,只能传递指针,所以需要指明长度。SizeParamIndex = 1表示index=1处是数组的长度,如果长度写在别的位置,需要修改。
常见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合在一起,导致代码大段飘红。。。注释掉就好了。
这是我的问题=。=
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfkbaj
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01