您的位置:首页 > 其它

如何生成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.html

2. 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: