如何生成DLL工程
2015-09-17 18:40
465 查看
如何生成,调用和调试DLL工程
在使用其他语言调用C/C++程序,通常会使用DLL工程文件。本篇文章介绍的内容包括以下几点:如何生成C/C++的DLL文件
如何在C#中调用DLL文件
如何调试DLL文件
如何生成C/C++的DLL文件
新建工程,选择“Visual C++”工程中的“Win32控制台程序”类型。工程设置中,将“应用程序类型”设置为“DLL”,“附加选项”设置为“空项目”。点击“完成”,则生产成了DLL工程文件。这里以将C++类导出为DLL为例。类的头文件和源文件分别如下:
/**********************************************/ /*FileName:DllDemo.h */ /**********************************************/ #ifdef DllDemoAPI #else #define DllDemoAPI _declspec(dllimport) #endif class Point { public: void Print(int *x, int *y, int xSize, int ySize); }; extern "C" { DllDemoAPI Point *Point_Create(); DllDemoAPI void Point_Print(Point *pt, int *x, int *y, int xSize, int ySize); DllDemoAPI void Point_Delete(Point *pt); }
/**********************************************/ /*FileName:DllDemo.cpp */ /**********************************************/ #define DllDemoAPI _declspec(dllexport) #include "DllTest.h" #include <stdio.h> extern "C" { DllDemoAPI Point* Point_Create() { return new Point(); } DllDemoAPI void Point_Print(Point* pPoint, int *x, int *y, int xSize, int ySize) { return pPoint->Print(x,y,xSize,ySize); } DllDemoAPI void Point_Delete(Point* pPoint) { delete pPoint; } } void Point::Print(int *x,int *y, int xSize, int ySize) { for (int i = 0; i < xSize; i++) { printf("x[%d]=%d\n",i,x[i]); } for (int i = 0; i < ySize; i++) { printf("y[%d]=%d\n",i,y[i]); } }
代码分析
代码中使用_declspec(dllimport)和_declspec(dllexport)进行DLL函数的导入和导出。
extern “C”的作用是使用C语言的编译逻辑导出函数,即函数名称则为定义的名称。而不会向C++一样给函数名加上前缀和后缀。
正是因为使用C语言的编译逻辑导出函数,所以无法对类直接进行导出,因为C语言不支持类。当然如果生成的DLL是给C++使用的,则不需要extern “C”关键字,也可以对类等C++支持的结构进行导出。
这里默认的调用是cdecl,如果需要使用stdcall或者fastcall进行调用,则需要另外进行声明。
如何在C#中调用DLL文件
在C#中调用C++的DLL有多种方法,例如使用Marshal模块, 托管DLL, COM组件等。这里介绍的是使用最常见的P/Invoke方法。在C#中调用上述工程的代码如下:
using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Linq; using System.Text; namespace ConsoleApplication { class Program { [DllImport("DLLTest.dll", EntryPoint = "Point_Create", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr Point_Create(); [DllImport("DLLTest.dll", EntryPoint = "Point_Print", CallingConvention = CallingConvention.Cdecl)] public static extern void Point_Print(IntPtr value, int[] x, int[] y, int xSize, int ySize); [DllImport("DLLTest.dll", EntryPoint = "Point_Delete", CallingConvention = CallingConvention.Cdecl)] public static extern void Point_Delete(IntPtr value); static void Main(string[] args) { IntPtr temp = Point_Create(); int[] x = new int[10]; int[] y = new int[10]; for (int i = 0; i < 10; i++) { x[i] = i; y[i] = i; } int xSize = 10; int ySize = 10; Point_Print(temp, x, y, xSize, ySize); Point_Delete(temp); } } }
代码分析
这里使用DllImport函数对DLL进行导入。
注意要将之前生成的DLL拷贝到exe文件所在的文件夹下。
如何调试DLL文件
在生成DLL的过程中,调试是必不可少的一步。调试的方式是写一个调用DLL中函数的工程,然后将该工程的exe文件设置为DLL工程的可执行文件即可。具体方法为在工程的属性页中,找到调试选项卡下的命令一行,然后将exe文件的路径添加进去,即可进行调试。常见问题
如何将多个类导出到一个DLL文件中可以尝试使用托管DLL或COM组件的方法。
当类使用其他类中的功能时,如何生成DLL文件
在这种情况下,将调用到的其他类的文件添加到DLL生成的工程中,则生成的DLL就包含了调用类中的功能。无需进行其他特殊设置。
参考文献
1.http://www.cnblogs.com/bigwangdi/archive/2012/11/23/2784535.html2. http://www.cppblog.com/suiaiguo/
3. /article/7722812.html
4. /article/10306478.html
5. /article/8958986.html
6. /article/9371629.html
7. http://www.swig.org/tutorial.html
8. http://stackoverflow.com/questions/315051/using-a-class-defined-in-a-c-dll-in-c-sharp-code
9. http://www.xinterop.com/index.php/category/net/
10. http://www.codeproject.com/Articles/6244/Step-by-Step-Calling-C-DLLs-from-VC-and-VB-Part
11. http://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class
12. http://www.codeproject.com/Questions/530172/Howplustoplusimportplusc-b-bplusclassplustoplusc
13. http://stackoverflow.com/questions/1170892/net-call-c-functions-from-c-sharp
14. https://msdn.microsoft.com/en-us/library/ms235281.aspx
15. http://blog.csdn.net/zhoubl668/article/details/3732238
相关文章推荐
- Android Make脚本简记
- Arcgis For Android 实现元素屏幕居中
- 谈谈session的生命周期
- Struts2 显示日期类型
- java.net.SocketException四大异常解决方案
- 用netbeans编的简易计算器
- OC-通知中心应用
- Linux netstat命令详解和使用例子(显示各种网络相关信息)
- Redis安装
- (转)如何创建Filter的属性页 [此博文包含图片] (2012-09-06 10:15:58) 转载 ▼ 标签: 杂谈 分类: DirectShow http://blog.csdn.net/
- CSS select样式优化 含jquery代码
- 关于Window Server2008 服务器上无法播放音频文件的解决方案
- JAVA分布式架构
- powerdesigner 通过jdbc连接 oracle数据库
- 第二周实践3--体验复杂度(2)汉诺塔
- hadoop2.6.0 完全分布式安装
- Spark调度系列-----3.SparkContext对象的创建和SparkContext的作用
- SharePoint研究之表单登录配置
- android: Intent启动activity
- IT职业道路的苦与甜