背景

一个项目,算法部分使用C++的openCV库编写图像处理程序,编译成dll,用户界面采用C#编写,去调用该dll暴露的接口。

C#编写的是托管代码,编译生成微软中间语言,而普通C++代码则编译生成本地机器码,这两种语言不能直接混合编程。常见的方式是:

1)将本机C++代码(指非托管C++)编译成一个dll,供C#调用,调用方法为 [DllImport(×××.dll)] 。但是这里只能从 DLL 导出函数,不能导出类(还没有测试能否导出变量)。不能导出类是因为本机C++是非托管的,与C#的语言方式不兼容。也就是说,不能将此类dll作为引用 添加到C#工程中,IDE会提示不是一个程序集。这种方法因为无法导出类,对习惯面向对象编程的人来说,使用起来也不方便。

2)利用CLR C++(指托管C++)编写输出类库,供C#使用,由于CLR C++和C#都符合CLS规范,所以两者可以无缝集成,在一个解决方案里包含这两种语言的项目。生成的DLL可以导出类。这种方法显然不适用于我的情况,因为openCV代码并非托管C++代码,无法直接编译成可供C#调用的类。

3)托管C++和C#一样编译成为微软中间语言,这样就可以和C#良好地通信,即可以在c#中使用托管C++类。同时,托管C++可以调用本地C++的类和函数,一个托管C++的程序集可以嵌套本地C++编译的机器码。这样的特征决定了托管C++可以成为C#和本地C++之间的良好桥梁。所以可以让C#以调用托管C++,而托管C++调用本地C++的类和函数。换句话说也就是用托管C++给本地C++代码做一个外壳供C#调用。这里的本地C++代码就是我们要调用的opencv库函数,托管C++代码就是我们基于openCV编写的图像处理函数。由于这些函数是托管代码,所以可以被C#直接调用。

本部分代码示例:

当我在C#窗体初始化的时候,调用了外部C++的dll时,抛出一个“正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码”的异常,程序就卡掉了。

解决方案:

在菜单中选择 “调试->异常”,打开异常设置窗口(也可通过快捷键Ctrl+Alt+E打开),在异常窗口中找到 “Managed Debuggin Assistants->LoaderLock”,将该项“引发”的状态框中的对勾去掉,最终设置结果如下图所示:

参考文章:

C#如何静态调用C++中的方法(静态调用dll)

在 WPF 中,使用 C++ 编写的 DLL 文件

C#调用opencv

C#.net 环境下使用OpenCV(一)

C#如何调用C++的dll的更多相关文章

  1. 调用Interop.zkemkeeper.dll无法使用解决方案

    调用Interop.zkemkeeper.dll无法使用 已经注册dll成功但是还是报错 检索 COM 类工厂中 CLSID 为 {00853A19-BD51-419B--2DABE57EB61F} ...

  2. c# 传递Null的string值导致的调用C++的dll报错 Attempted to read or write protected memory.

    c# 调用C++的dll报错 Attempted to read or write protected memory:   原因是:c# 传递Null的string值导致的,将Null改为string ...

  3. Node调用C++(dll)

    最近开始搞毕设了,打算用自己拿手的js来搞,但是仿佛入坑了,Node还不是很熟.总之,兵来将挡,水来土掩嘛,带着问题学习才是最高效的. 折腾1:Node 调用 C++ 刚开始,虽然我老师把dll文件给 ...

  4. golang调用c++的dll库文件

    最近使用golang调用c++的dll库文件,简单了解了一下,特作此笔记:一.DLL 的编制与具体的编程语言及编译器无关 dll分com的dll和动态dll,Com组件dll:不管是何种语言写的都可以 ...

  5. vs2010下C++调用lib或dll文件

    注: DLL:表示链接库,包含dll,lib文件: dll: 表示my.dll文件 lib: 表示my.lib文件 C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1  设置工程的 ...

  6. paip.java c# .net php python调用c++ c dll so windows api 总结

    paip.java c# .net  php python调用c++ c dll so windows api 总结 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来 ...

  7. c++builder调用VC的dll以及VC调用c++builder的dll

    解析__cdecl,__fastcall, __stdcall 的不同:在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式. 比如说__cdecl,它是标准的c方法的堆栈调用方式,就 ...

  8. LabView调用C#混合模式dll

    在一些特定要求下,我们的C#可能需要制作dll给LabView进行调用,并且我们不能够保证C#的程序是完全自己写而不调用第三方的dll库.很多时候我们需要使用诸如Sqlite.Net.AForge.N ...

  9. 关于c#调用c/c++ dll遇到的问题总结

    前段时间公司做了个winform程序,需要调用c 的dll去读取卡号的程序,期间遇到些问题,下面来分享下 一.dll路径问题 相信很多开发者都会遇到这个问题,我总结了下我现在有3总方式去解决这个问题: ...

  10. C#调用C++的DLL搜集整理的所有数据类型转换方式

    //C#调用C++的DLL搜集整理的所有数据类型转换方式,可能会有重复或者多种方案,自己多测试 //c++:HANDLE(void *) ---- c#:System.IntPtr //c++:Byt ...

随机推荐

  1. CSS--position:relative和position:absolute

    position:relative相对定位 1. 如何定位?每个元素在页面的普通流中会“占有”一个位置,这个位置可以理解为默认值,而相对定位就是将元素偏离元素的默认位置,但普通流中依然保持着原有的默认 ...

  2. Python打包—Pyinstaller

    2018-09-27 21:12:05   一 前言 在windows平台学习python的过程中,你肯定会遇到需要把.py脚本打包成.exe的情形,如此,至少有两方面的好处:第一,你的代码保密性更好 ...

  3. tensorflow中的Supervisor

    tf.train.Supervisor()可以帮我们简化一些事情,可以保存模型参数和Summary,它有以下的作用: 1)自动去checkpoint加载数据或初始化数据 ,因此我们就不需要手动初始化或 ...

  4. Linux:Day3 文件系统

    Linux的文件系统: 根文件系统(rootfs):root filesystem /boot:引导文件存放目录:内核文件(vmlinuz).引导加载器(bootloader,grub)都存放于此目录 ...

  5. 联想Y7000安装Ubuntu16.04/Win10双系统,wifi问题,显卡驱动和CUDA10安装

    https://blog.csdn.net/la9881275/article/details/86720752 Ubuntu16.04系统安装拿到Ubuntu镜像制作装机优盘,这里就不写了.我的优盘 ...

  6. emqtt在centos6下的安装

    1 emqtt下载地址 http://www.emqtt.com/downloads 右键 复制链接 http://www.emqtt.com/downloads/3011/centos6 2 打开服 ...

  7. nginx之十三:搭建 nginx 反向代理用做内网域名转发

      user www www;worker_processes 1;error_log logs/error.log;pid logs/nginx.pid;worker_rlimit_nofile 6 ...

  8. gooderp安装

    在做ODOO的前提下需要PostgreSQL,  SO.... #!/bin/bashPID=`echo $$`echo -e "\033[35m该脚本只在CentOS 7.4.1708版本 ...

  9. HRBUST - 2347 - 递归画图 - vj大一上寒假训练2.11

    其他题可由本题变形得到. 思路:利用坐标dfs搜索. 注意:1,初始化.2,坐标实时更新(x,y) 代码: #include<iostream> #include<cstdio> ...

  10. Spring Boot 之使用 Json 详解

    Spring Boot 之使用 Json 详解 简介 Spring Boot 支持的 Json 库 Spring Web 中的序列化.反序列化 指定类的 Json 序列化.反序列化 @JsonTest ...