介绍

每种语言都有其优势和特点,复杂的项目一般需要2种及以上的语言,这样才能发挥每种语言的优势。这里就介绍一下C#如何调用VC的DLL

项目创建

打开VS2010,因为涉及到两个程序,这里先创建一个空的解决方案:

然后再来创建一个VC的DLL项目:

选择Win32项目模板:

选择应用程序的类型为DLL:

这里不用勾选“导出符号”,稍后自己来写导出就行。点击完成后生成如下文件:

dllmain.cpp文件不用修改,只在Win32Dll.cpp中添加我们用来测试的函数即可:

就简单写了个加减函数,下面再创建一个C#项目,来测试DLL的调用:

这里只是简单测试VC的DLL,并不需要界面,所以创建一个控制台应用程序即可,文件结构如下:

为了导入DLL的函数,再添加一个C#类:

在生成的TestDll类中导入VC库定义的函数声明:

这里注意两个地方,库函数名字就是VC项目生成的库的名字(注意别写错),调用方式要选择“CallingConvention.Cdecl”。而看到DllImport画红线报错了,需要添加“InteropServices”引用:

导入库函数后,就可以在main函数中编写调用代码了:

最后一行ReadLine()是防止控制台程序一闪而逝的,到这里测试代码都写完了。先别着急编译,因为C#程序要调用DLL必须保证生成的exe和dll文件在同一目录,所以需要改一下VC程序生成dll的路径:

两个项目在一个解决方案下,所以前面路径是$(SolutionDir)\,C#程序默认生成路径是项目文件夹的bin目录。又因为解决方案下有多个项目,还要把C#程序设置为启动项目:

设置好后就可以编译运行了:

正常情况就顺利出结果了,如果报错,可能就是哪个路径设置不对,再仔细核对下exe和dll是否都生成在同一目录了:

字符串参数传递

上面只是最简单的调用测试,实际传参比较麻烦的就是字符串了,由于C#操作的是数组,而VC使用指针传参,下面就看看这俩之间如何转化。先写VC库中函数:

这里写了个输入输出函数,根据输入不同返回不同的字符串,下面看看C#里如何调用,同样TestDll类中先导入声明:

在C#里面指针参数都改为数组了,但前面有In或Out属性来区分。再来写main里面的调用:

这样写好后运行一下:

结果显示是没问题,但调试看str的值:

字符串变量后面跟这么多\0总不好,这里需要处理一下:

加一行代码就搞定,C#就是这么方便。那位说了,C#不是也能使用指针吗,有人就是不习惯使用数组。那好,我们再来写一个传指针的函数:

由于使用了std命名空间,需要加上头文件:

#include <iostream>

注意看一下TestDll类中声明与之前有什么不同:

这里由于参数是指针,所以要加上unsafe修饰符,这样编译才能顺利进行。这里有个需要注意的地方,C#定义的参数是char,为什么VC那边是wchar_t呢?熟悉C#应该知道,其使用的是Unicode编码,char是16位而非VC里面的8位,因此VC必须用对应的宽字符变量。再看看调用代码:

unsafe修饰符报错了,根据提示,得在项目属性里面设置“允许不安全代码”:

这样编译就没问题了:

当然这里只是为了指针参数测试,一般不推荐这种方式,因为传递的指针空间大小另一边无法检测,容易造成内存溢出。

传递结构体参数

下面再来个复杂点的,如果VC的库里面有类定义,那么C#如何调用呢?首先VC创建一个UserInfo类,添加头文件:

敲入类代码:

然后写这个类的创建函数:

不要直接传参类变量,所以这里又定义一个User结构体作为参数进行传递,那么C#那边如何声明呢:

同样定义了一个User结构体,而Create函数返回值只是一个IntPtr指针,调用的时候再转换为对应的结构体:

由于用到Marshal类,所以需要引入命名空间:

using System.Runtime.InteropServices;

再次编译运行:

细心读者可能注意到VC里面的User变量是malloc出来的,使用Marshal.PtrToStructure传给C#的时候是不是就托管了,以后自动释放呢?答案是否定的,因为Marshal.PtrToStructure会进行内存拷贝的,C#只负责释放拷贝后的自己管理的变量,而原来VC里的User还需要我们自己释放。为此编写释放代码测试下:

C#中声明该函数:

调用测试:

我们看到,在参数传递之后就释放了VC库里User变量,如果没进行内存拷贝,下面的输出调用肯定要报错的,可实际运行仍然显示正常,说明Marshal.PtrToStructure完成了内存拷贝。关于这一点使用时要非常注意,C#的内存自动管理,而VC库的内存还是需要自己管理,否则容易造成内存泄露。

调用MFC的DLL

上面讲的都是调用Win32的DLL,那么C#能不能也调用MFC的DLL呢?下面来测试一下,再往解决方案里添加个MFC的项目:


按照默认来创建即可,然后添加一个MFC类:

填好类名和基类:

点击完成,然后设计一个简单的对话框界面:

然后在MFCDll.cpp文件中编写导出函数:

在C#程序中声明该函数:

注意DLL的名称要与新建的MFC项目生成的名称一致,这个没有传参,直接在main函数中调用即可:

TestDll.ShowDlg();
Console.ReadLine();

同样别忘设置MFCDll项目的生成路径为C#的bin路径:

编译后确保3个项目都生成成功,然后运行:

好了,先写到这里吧,下一篇再介绍VC调用C#的DLL。

C#与VC相互调用之C#调用VC的DLL相关推荐

  1. C#与VC相互调用之VC调用C#的DLL库

    介绍 在之前的博文 C#与VC相互调用之C#调用VC的DLL https://blog.csdn.net/xinxin_2011/article/details/86704660 里面讲了C#程序如何 ...

  2. VC++动态库封装及调用

    https://blog.csdn.net/zhangfuliang123/article/details/71515796 一直对动态库的封装理解不是很透彻,虽然之前写过一个Demo,不过并没有真正 ...

  3. c 的dll php调用方法,PHP调用C#开发的dll类库方法,_PHP教程

    PHP调用C#开发的dll类库方法, 有的时候,我们需要在php中利用到其他语言编写的dll类库,如C#编写的dll,方法就是利用PHP new COM方法来调用,在调用之前先要把dll库注册并把程序 ...

  4. aop统计请求数量_使用SpringAOP获取一次请求流经方法的调用次数和调用耗时

    引语### 作为工程师,不能仅仅满足于实现了现有的功能逻辑,还必须深入认识系统.一次请求,流经了哪些方法,执行了多少次DB操作,访问了多少次文件操作,调用多少次API操作,总共有多少次IO操作,多少C ...

  5. 【C/C++服务器开发】同步与异步、阻塞与非阻塞、同步调用和异步调用的概念

    同步与异步 首先我们要明确的是,同步和异步都是针对两个或者两个以上的事物来说的.比如当我们在网上购物看中一件物品,然后去浏览该商品详情的时候,首先页面会先发送一个请求,后台服务器查询对应商品的相关数据 ...

  6. 直观讲解一下 RPC 调用和 HTTP 调用的区别!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:浮生忆梦 blog.csdn.net/m0_3811 ...

  7. 直观讲解一下RPC调用和HTTP调用的区别

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:浮生忆梦 blog.csdn.net/m0_38110132 ...

  8. 把接口调用打成jar包的类怎么写_直观讲解RPC调用和HTTP调用的区别

    来源 :浮生忆梦 很长时间以来都没有怎么好好搞清楚RPC(即Remote Procedure Call,远程过程调用)和HTTP调用的区别,不都是写一个服务然后在客户端调用么?这里请允许我迷之一笑~N ...

  9. oracle创建函数和调用存储过程和调用函数的例子(区别)

    创建函数: 格式:create or replace function func(参数 参数类型) Return number Is Begin --------业务逻辑--------- End; ...

  10. C++对象模型3——vptr的位置、手动调用虚函数、从汇编代码看普通调用和多态调用

    一.vptr的位置 class test { public:int i; virtual void testfunc() {} };int main() {test a;char* p1 = rein ...

最新文章

  1. Java私有变量是否可继承
  2. Python3 文件的重命名
  3. libevent简介和使用【转】
  4. 宁波理工大学计算机程序设计培训,拼搏在程序设计前列——专访ACM大赛冠军浙江大学宁波理工学院FBH团队...
  5. android启动白屏的分析,Android 启动白屏,跳转黑屏以及冷启动优化
  6. 牛客练习赛70 重新排列
  7. UNIX(多线程):18---异步任务提供者(Provider) 介绍(续)
  8. 专访合一智芯杨桦:做AI芯片核心技术的底层设计师
  9. simulink将值传递给mask封装下的模块
  10. 具体数学-第7课(取整基础)
  11. 多个线程并发执行完成后再执行主线程-java(有点内容版)
  12. MySQL 数据库管理之 --- SQL 语言进阶二
  13. 腾讯x5内核(TBS)集成使用详解(webView视频播放)
  14. 电路逻辑门图形符号汇总
  15. 2021深圳杯数学建模D题
  16. vue -使用阿里矢量图
  17. 爬虫——Scrapy框架案例二:阳光问政平台
  18. 盛世乐居回应近期股价波动
  19. C语言中常见的转义字符总结
  20. 手机验证码接收注册新账户

热门文章

  1. 孟岩:参与设计20多个区块链经济系统后,我总结出4个原则和7个陷阱 |区块链捕手
  2. 【工作感想】 关于前后端分离的问题
  3. 如何免费且快速的搭建个人网站
  4. 金蝶KIS专业版V14.1下载链接,金蝶KIS专业版V14.1新增功能介绍 安装包下载地址
  5. 目标导向型思维, 利他思维,迭代思维, 用忙碌打败无聊,整合型思维 重视运动
  6. leetcode 热点——排列组合问题
  7. 玩转软路由 篇四:软路由中OpenWRT作为旁路由的安装设置教程
  8. Linux从删库到跑路--常用命令
  9. Php打印连续纸,针式打印机打印241*297MM连续纸时总按A4纸长度多走一部分白纸?
  10. 提交网址到bing搜索引擎