c#代码
using System; using System.Colle<img src="http://img.bbs.csdn.net/upload/201704/11/1491899383_919628.png" alt="">.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下面是.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出现的问题是
然后上网找了很多资料,实在是没用一个合适的解决方案、只能来请求下帮助,怎么解决?然后是dll制作出了问题还是c#d调用dll本来就存在一些问题呢?
解决方案
10
不要做A语言代码修改为B语言代码的无用功。
也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。
只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。
即可很方便地让A、B两种语言之间协调工作。
例如:
A将请求数据写到文件a.txt,写完后改名为aa.txt
B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,改名为bb.txt
A发现bb.txt存在时,读取其内容,读完后删除bb.txt
以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。
除非A或B不支持判断文件能否存在、文件读写和文件更名。
但是谁又能举出不支持判断文件能否存在、文件读写和文件更名的开发语言或开发环境呢?
可以将临时文件放在RamDisk上提高效率减少磨损磁盘。
数据的结构很复杂的话,文本文件的格式问题可参考json或xml
共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出本人现在能想到的:
·进程之间松耦合
·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。
·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。
·方便在线开关服务,只需删除或创建该临时文本文件即可。
·方便实现分布式和负载均衡。
·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满)
·……
“跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边,
回头是“使用共享纯文本文件进行信息交流”的岸!
也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。
只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。
即可很方便地让A、B两种语言之间协调工作。
例如:
A将请求数据写到文件a.txt,写完后改名为aa.txt
B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,改名为bb.txt
A发现bb.txt存在时,读取其内容,读完后删除bb.txt
以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。
除非A或B不支持判断文件能否存在、文件读写和文件更名。
但是谁又能举出不支持判断文件能否存在、文件读写和文件更名的开发语言或开发环境呢?
可以将临时文件放在RamDisk上提高效率减少磨损磁盘。
数据的结构很复杂的话,文本文件的格式问题可参考json或xml
共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出本人现在能想到的:
·进程之间松耦合
·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。
·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。
·方便在线开关服务,只需删除或创建该临时文本文件即可。
·方便实现分布式和负载均衡。
·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满)
·……
“跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边,
回头是“使用共享纯文本文件进行信息交流”的岸!
20
看到过一个调用C++ dll的最常见的问题就是C++ 用指针而C#不用指针的问题,你这个会不会是这个问题?
30
那就应该是这个问题了,你用IntPtr试试看
40
EntryPoint = “?smallTarget@@YA?AV?$Point_@H@cv@@PBD@Z”
这个入口好蛋疼。封装dll的时候选择C编译链接模式嘛。C++支持函数重载,所以入口怪怪的
看异常不像是内存出错,怀疑就是入口没搞好
这个入口好蛋疼。封装dll的时候选择C编译链接模式嘛。C++支持函数重载,所以入口怪怪的
看异常不像是内存出错,怀疑就是入口没搞好