C#程序调用C++动态库(dll文件)遇到的坑及解决

 更新时间:2023年08月14日 11:03:37   作者:CC_21H  
这篇文章主要介绍了C#程序调用C++动态库(dll文件)遇到的坑及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

C#程序调用C++程序DLL遇到的坑

这两天有一个需求就是C++写的程序,给外包公司写界面,他们用的是C#写的,所以我得生成C++动态库(dll文件)给他们调用,过程中遇到了很多坑

这里记录下来给大家参考。

C#调用c++动态库(dll)方法

可以参考:C#调用C++的dll两种实现(托管与非托管)

总结一下就是先建一个C++程序,建立的时候选择dll类型。(或者右击项目-属性-常规-配置类型里将exe类型修改为dll类型)

然后建立一个头文件(test.h),一个c++文件(test.cpp)

test.h文件声明一个函数

extern "C"  __declspec(dllexport) int add(int a, int b);

test.cpp文件写函数体,并导入test.h头文件

#include"test.h"
extern "C"  __declspec(dllexport) int add(int a, int b){
	return a+b;
};

然后右击项目,点击重新生成

并记录下生成dll的路径

然后创建一个c#程序用DllImport语句导入,路径是前面dll的路径

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
    class Program
    {
		//这里注意,一个函数导入一次,如果是两个函数就导入两次,路径是前面生成的dll路径
        [DllImport(@"D:\CC\Project7_源码版本_dll\Project7\Project7.dll", EntryPoint = "add")]
        extern static int add(int a,int b);
        static void Main(string[] args)
        {
            Console.WriteLine(add(2,3));
            Console.ReadKey();
        }
    }
}

然后在main函数里进行测试,运行即可

当然,如果真有这么简单也没必要发这篇博客了,你可能会遇到各种各样的坑,让你绝望,下面列举我遇到过的坑。

问题1:报错System.DllNotFoundException

这个问题首先要检查生成的dll和C#运行的环境位数是不是一致的,要么都是32位,要么都是64位。

如果位数没问题,那就一定是你把dll移动到其他地方去了,dll在哪生成的就在哪放在,不要乱移动啊!!!

在Debug目录下生成就Debug目录,在Release目录下生成就Release。DllImport写对应的路径就行了。

如果还是不行,建议看看其他的博客……反正博主这个问题没困扰多久就解决了

问题2:报错System.BadImageFormatException

这个,是我苦恼了两天的报错,一直没办法解决。最后没办法找了我室友c++大神帮忙解决了,就是下面这个一流软件架构师。

主要问题还是位数的问题,程序调用了位数不一致的库。

解决方案1:

生成和调试都用32位的。

解决方案2:

如果你就是想用64位的,那就右击C#程序-属性-生成-目标平台改为x64(或者Any CPU,取消勾选首选32位)

在这里插入图片描述

在这里插入图片描述

就是这个问题,你觉得自己明明选择了x64运行,可它其实还是默认32位运行的。

如果只要调用加法的测试函数,基本上就只会碰到上面两个问题。如果你想调用自己的程序,你可能会遇到下面这些问题

问题3:参数有字符串,报错System.AccessViolationException

废话不多说,直接上解决方案:

cpp文件参数类型写char*,在函数体里面可以直接把char* 类型赋值给string类型,但是参数必须是char*类型

extern "C"  __declspec(dllexport) int add(char* str);

c#程序参数写string

[DllImport(@"D:\\test.dll", EntryPoint = "add")]
extern static int add(string str);

还有一种可能会报错System.AccessViolationException,就是函数不对应,我有次是 EntryPoint = "add"这个忘记改成对应的函数名了,也是报的这个错,所以仔细检查,把函数名对应起来。

问题4:如何返回多个值

好像有种方法是返回结构体,但我尝试了一下没成功就用了另一种办法,一下就成功了。

那就是,传地址:

cpp文件参数类型写地址int*

extern "C"  __declspec(dllexport) int add(int* a,int* b){
 	a++;
 	b++;
 	return a;
};

c#程序参数写ref int

[DllImport(@"D:\\test.dll", EntryPoint = "add")]
extern static int add(ref int a,ref int b);
 static void Main(string[] args)
        {
        	//这里必须先初始化
        	int a=0;
        	int b=0;
            Console.WriteLine(add(ref a,ref b));
            Console.WriteLine(a);
            Console.WriteLine(b);
            Console.ReadKey();
        }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 教你创建一个带诊断工具的.NET镜像

    教你创建一个带诊断工具的.NET镜像

    本文编写的初衷是因为在群里有很多小伙伴遇到生产环境性能问题的时候,.NET的runtime镜像中没有带一些工具,安装和使用起来很麻烦,所以分享一些我们公司内部一些技巧,对.NET镜像带诊断工具相关知识感兴趣的朋友一起看看吧
    2022-07-07
  • C#画笔Pen用法实例

    C#画笔Pen用法实例

    这篇文章主要介绍了C#画笔Pen用法,实例分析了画笔Pen绘制图形的相关技巧,需要的朋友可以参考下
    2015-06-06
  • C#连接db2数据库的实现方法

    C#连接db2数据库的实现方法

    本篇文章是对C#连接db2数据库的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 一款域名监控小工具 Domain(IP)Watcher 实现代码

    一款域名监控小工具 Domain(IP)Watcher 实现代码

    域名是否正常,网站是否可以正常访问是很头痛的问题,怎样简单地监控域名是否可以正常访问呢,这里发布一款域名监控小工具:Domain(IP)Watcher
    2011-11-11
  • c#转义字符串中的所有正则特殊字符方法示例

    c#转义字符串中的所有正则特殊字符方法示例

    这篇文章主要介绍了c#转义字符串中的所有正则特殊字符,大家可以参考使用
    2013-12-12
  • C#操作mysql数据库的代码实例

    C#操作mysql数据库的代码实例

    这篇文章为大家提供了一个C#操作mysql数据库的实例,大家可以参考使用
    2013-11-11
  • C# 可空类型的具体使用

    C# 可空类型的具体使用

    这篇文章主要介绍了C# 可空类型的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • c# 如何更简单的使用Polly

    c# 如何更简单的使用Polly

    这篇文章主要介绍了c# 如何更简单的使用Polly,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • Unity ScrollRect实现轨迹滑动效果

    Unity ScrollRect实现轨迹滑动效果

    这篇文章主要为大家详细介绍了Unity ScrollRect实现轨迹滑动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • C#算法之无重复字符的最长子串

    C#算法之无重复字符的最长子串

    这篇文章介绍了C#算法之无重复字符的最长子串,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01

最新评论