C#调用c++dll提示:外部组件发生异常。

时间:2022-08-31 09:14:56
c#程序
using System;
using System.ColleC#调用c++dll提示:外部组件发生异常。.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        [DllImport("smallT_BJ.dll", EntryPoint = "?smallTarget@@YA?AV?$Point_@H@cv@@PBD@Z",
ExactSpelling = true,CallingConvention = CallingConvention.Cdecl)]  
// EntryPoint 这个比较复杂的部分是通过dependency查询到的函数名,与之前定义的函数名smallTarget多了很多字符
        public static extern Point smallTarget(string path);
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            string path = " C:\\1.bmp";
            Point point = new Point();
            point = smallTarget(path);
        }
    }
}

c#部分就是这么多东西,很简单的一个调用dll的程序。
c++dll下面是.h文件的内容

#include <windows.h>
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <opencv2\opencv.hpp>
#include <fstream>
#include <memory>
#include <stdlib.h>
#include <math.h>
#include <time.h>
using namespace std;
using namespace cv;
#ifdef SMALLT_BJ_EXPORTS
#define SMALLT_BJ_API __declspec(dllexport)
#else
#define SMALLT_BJ_API __declspec(dllimport)
#endif
SMALLT_BJ_API Mat filters(Mat source, int thresholdin);
SMALLT_BJ_API Mat filterspatial2(Mat source, int th);
SMALLT_BJ_API void cmedian(Mat src, Mat dst, int innerbox_size, int outerbox_size);
SMALLT_BJ_API Mat prefilter(Mat source);
SMALLT_BJ_API vector<Mat> getSuspects(Mat& frame, Mat src, int box_size, vector<Point>& LeftUpPoints, vector<vector<Point>>& cont);
SMALLT_BJ_API Point smallTarget(const char* file);

其他的都是乱码就不贴出来了,我在c#执行文件的目录下面(存放位置肯定没又问题,bin\Debug目录下)放了4个可能需要用到的文件,分别是.dll文件.h文件,.lib文件,.exp文件。在调用这个dll文件之前我用dependency测试了一下dll,发现缺少几个opencv方面的动态库,然后就加了相应的dll文件加在c#程序的目录下,后来又检测发现又缺少了更多的dll,然后又添加了相应的dll,最后检测不缺少dll,但是出现的问题是:“警告: 由于在延时加载依赖模块中丢失导入函数,至少有一个模块具有不能解析的导入。”。其中dll文件在别人给我的时候在我的电脑上进行了测试,并没问题,可以运行通过。
然后我在c#上进行调用dll出现的问题是 C#调用c++dll提示:外部组件发生异常。
然后上网找了很多资料,实在是没用一个合适的解决方案、只能来请求下帮助,怎么解决?然后是dll制作出了问题还是c#d调用dll本来就存在一些问题呢?谢谢啊。有合适的答案还得加分。。谢谢啊。急急急!!!!

13 个解决方案

#1


楼主代码明显对dl内部实现l一无所知,建议:
c++写的dll,用vc++写个简单测试程序试试再说,成功了再到c#下用。

#2


引用 1 楼 xuggzu 的回复:
楼主代码明显对dl内部实现l一无所知,建议:
c++写的dll,用vc++写个简单测试程序试试再说,成功了再到c#下用。

在VS2013上进行测试了,并没用问题啊。还有,我是真的对dll内部实现一无所知 C#调用c++dll提示:外部组件发生异常。

#3


既然用VC测试没问题,又不知道smallTarget内部实现,这问题还真挺难的。
一般这种异常都是类型不对应引起的,或者缺关联的库。其它方面就算有问题提示的异常也不是这种,
楼主查查c++中定义的和c#的一样不?还有注意编译平台要一致。其它可能实在想不到。。。

#4


查point返回值类型一致性

#5


对于这个,如果你确实需要从C# 呼叫。
建议你先创建一个 C++/CLR 的包装。
这样,都不需要导入注入 mat 之类的东西。
而且呼叫 .dll 操作都在 C++ 内部。

写这种 dllexport 的家伙,应该被打死。
他根本不懂得导出符号。

#6


引用 3 楼 xuggzu 的回复:
既然用VC测试没问题,又不知道smallTarget内部实现,这问题还真挺难的。
一般这种异常都是类型不对应引起的,或者缺关联的库。其它方面就算有问题提示的异常也不是这种,
楼主查查c++中定义的和c#的一样不?还有注意编译平台要一致。其它可能实在想不到。。。

smallTarge是我同学写的,她知道内部实现,而且运行了1个多月没用问题。编译平台都是vs2012,用depedency查旬,缺少的库我都加了,那么按你说的可能就是类型不一样了。那我好好查查看。谢谢

#7


引用 4 楼 xuggzu 的回复:
查point返回值类型一致性

应该不是这个原因,因为之前做了一个a.dll,输入输出都和这个dll一样,只不过是a.dll的内部实现的功能比较简单,然后运行成功了

#8


引用 5 楼 Saleayas 的回复:
对于这个,如果你确实需要从C# 呼叫。
建议你先创建一个 C++/CLR 的包装。
这样,都不需要导入注入 mat 之类的东西。
而且呼叫 .dll 操作都在 C++ 内部。

c#呼叫是指调用dLl吗?还是指什么,创建c++包装是指对这个dll进行包装还是什么?我对c++不太了解,所以很多不太明白。。谢谢啊

#9


既然你同学写的,把她的代码拿来,就这个函数的代码拿来,你自己写个一样的smalltarget做成dll,然后用c#试,之后:
1. 无问题,那就是她编译环境和你不同,检查。
2. 同样问题,将函数中可能有问题代码一点点删除,做多次测试直到没问题为止,即可定位问题所在。

#10


引用 9 楼 xuggzu 的回复:
既然你同学写的,把她的代码拿来,就这个函数的代码拿来,你自己写个一样的smalltarget做成dll,然后用c#试,之后:
1. 无问题,那就是她编译环境和你不同,检查。
2. 同样问题,将函数中可能有问题代码一点点删除,做多次测试直到没问题为止,即可定位问题所在。

谢谢啊。现在出现了一个问题,就是调用我调用dll,每次输入相同的值,返回的却每次都不同的数据。c++dll中输入类型是const char*,我c#这边输入的是string,c++那边输出的是Point,c#这边也是point
   [DllImport("smallT_BJ.dll", EntryPoint = "test", CallingConvention = CallingConvention.Cdecl)]
       public static extern Point test(string path);

#11


opencv 的 Point 和 C# 里面的Point 是不一致的。
我建议你使用 CLR 的包装,然后再在 C#  里面使用。

#12


楼上Saleayas的看法和我相近,你查查Point一致性。
至于你刚说的测试代码每次返回值不同,一调试就清楚了啊!你自己的代码很容易调试。
const char*===string,这个类型对应关系不会有问题。还是建议拿你同学的代码逐步测试。

#13


切换Framework版本看看,我现在就是这个问题,切换了就好了,但是我在找如何处理版本兼容的问题,有大佬知道吗,嘤嘤嘤

#1


楼主代码明显对dl内部实现l一无所知,建议:
c++写的dll,用vc++写个简单测试程序试试再说,成功了再到c#下用。

#2


引用 1 楼 xuggzu 的回复:
楼主代码明显对dl内部实现l一无所知,建议:
c++写的dll,用vc++写个简单测试程序试试再说,成功了再到c#下用。

在VS2013上进行测试了,并没用问题啊。还有,我是真的对dll内部实现一无所知 C#调用c++dll提示:外部组件发生异常。

#3


既然用VC测试没问题,又不知道smallTarget内部实现,这问题还真挺难的。
一般这种异常都是类型不对应引起的,或者缺关联的库。其它方面就算有问题提示的异常也不是这种,
楼主查查c++中定义的和c#的一样不?还有注意编译平台要一致。其它可能实在想不到。。。

#4


查point返回值类型一致性

#5


对于这个,如果你确实需要从C# 呼叫。
建议你先创建一个 C++/CLR 的包装。
这样,都不需要导入注入 mat 之类的东西。
而且呼叫 .dll 操作都在 C++ 内部。

写这种 dllexport 的家伙,应该被打死。
他根本不懂得导出符号。

#6


引用 3 楼 xuggzu 的回复:
既然用VC测试没问题,又不知道smallTarget内部实现,这问题还真挺难的。
一般这种异常都是类型不对应引起的,或者缺关联的库。其它方面就算有问题提示的异常也不是这种,
楼主查查c++中定义的和c#的一样不?还有注意编译平台要一致。其它可能实在想不到。。。

smallTarge是我同学写的,她知道内部实现,而且运行了1个多月没用问题。编译平台都是vs2012,用depedency查旬,缺少的库我都加了,那么按你说的可能就是类型不一样了。那我好好查查看。谢谢

#7


引用 4 楼 xuggzu 的回复:
查point返回值类型一致性

应该不是这个原因,因为之前做了一个a.dll,输入输出都和这个dll一样,只不过是a.dll的内部实现的功能比较简单,然后运行成功了

#8


引用 5 楼 Saleayas 的回复:
对于这个,如果你确实需要从C# 呼叫。
建议你先创建一个 C++/CLR 的包装。
这样,都不需要导入注入 mat 之类的东西。
而且呼叫 .dll 操作都在 C++ 内部。

c#呼叫是指调用dLl吗?还是指什么,创建c++包装是指对这个dll进行包装还是什么?我对c++不太了解,所以很多不太明白。。谢谢啊

#9


既然你同学写的,把她的代码拿来,就这个函数的代码拿来,你自己写个一样的smalltarget做成dll,然后用c#试,之后:
1. 无问题,那就是她编译环境和你不同,检查。
2. 同样问题,将函数中可能有问题代码一点点删除,做多次测试直到没问题为止,即可定位问题所在。

#10


引用 9 楼 xuggzu 的回复:
既然你同学写的,把她的代码拿来,就这个函数的代码拿来,你自己写个一样的smalltarget做成dll,然后用c#试,之后:
1. 无问题,那就是她编译环境和你不同,检查。
2. 同样问题,将函数中可能有问题代码一点点删除,做多次测试直到没问题为止,即可定位问题所在。

谢谢啊。现在出现了一个问题,就是调用我调用dll,每次输入相同的值,返回的却每次都不同的数据。c++dll中输入类型是const char*,我c#这边输入的是string,c++那边输出的是Point,c#这边也是point
   [DllImport("smallT_BJ.dll", EntryPoint = "test", CallingConvention = CallingConvention.Cdecl)]
       public static extern Point test(string path);

#11


opencv 的 Point 和 C# 里面的Point 是不一致的。
我建议你使用 CLR 的包装,然后再在 C#  里面使用。

#12


楼上Saleayas的看法和我相近,你查查Point一致性。
至于你刚说的测试代码每次返回值不同,一调试就清楚了啊!你自己的代码很容易调试。
const char*===string,这个类型对应关系不会有问题。还是建议拿你同学的代码逐步测试。

#13


切换Framework版本看看,我现在就是这个问题,切换了就好了,但是我在找如何处理版本兼容的问题,有大佬知道吗,嘤嘤嘤