您的位置:首页 > 编程语言 > C语言/C++

C#调用C++ DLL的方式

2013-07-31 08:48 253 查看
动态链接库(DLL)是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。可以说在windows操作系统中随处可见,打开主分区盘下的system32。在一些项目中,如果有大量运算或者涉及大量算法时通常使用C或C++语言封装成一个dll,开放一些接口供其他程序调用。

下面是写的一个简单的dll代码,主要做示例,功能非常简单

1、dll提供外部调用的方法

extern "C" _declspec(dllexport) int Max(int a,int b);
extern "C" _declspec(dllexport) int Sum(int a,int b);
extern "C" _declspec(dllexport) int Min(int a,int b);


2、方法的实现

int Max(int a,int b)
{
if(a>b)
return a;
else
return b;
}

int Sum(int a,int b)
{
return a+b;
}

int Min(int a,int b)
{
if(a>b)
return b;
else
return a;
}


本文主要是介绍使用C#如何调用DLL不是重点,只做简单的介绍

一、C#调用DLL

在使用C#调用C++,需要使用系统Kernel32.dll来导入dill,一般需要如下三个函数

[DllImport("Kernel32",SetLastError=true)]
private static extern int GetProcAddress(int handle,string funcName);

[DllImport("Kernel32",SetLastError=true)]
private static extern int LoadLibrary(string dllPath);

[DllImport("Kernel32",SetLastError=true)]
private static extern int FreeLibrary(int handle);


其中:

LoadLibrary方法用来导入Dll

FreeLibrary方法用来释放Dll

GetProcAdress方法用来获取Dll中的方法访问的地址。

然后需要在C#中建立一个和C++中方法对应的方法,以便在C#中调用,我们定义三个委托来完成这件事:

public delegate int Max(int a, int b);

public delegate int Min(int a, int b);

public delegate int Sum(int a, int b);


然后我们定义三个委托的实例,使用上面的GetProAdress方法把地址指向委托实例的地址。全部代码如下:

private int dllHandle = 0;

public Max ProMax
{
get;
set;
}

public Min ProMin
{
set;
get;
}

public Sum ProSum
{
get;
set;
}

// 获取dll中的接口地址
private static Delegate GetAddress(int dllModule, string functionname, Type t)
{
int addr = GetProcAddress(dllModule, functionname);

if (addr == 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);
}

public void FreeLinbary()
{
if (this.dllHandle >= 32)
{
FreeLibrary(this.dllHandle);
}
}

/// <summary>
/// 加载Dll
/// </summary>
/// <returns>是否加载Dll成功</returns>
public int LoadDll(string dllPath)
{
this.dllHandle = LoadLibrary(dllPath);

if (this.dllHandle >= 32)
{
this.ProMax = (Max)GetAddress(dllHandle, "Max", typeof(Max));
this.ProMin = (Min)GetAddress(dllHandle, "Min", typeof(Min));
this.ProSum = (Sum)GetAddress(dllHandle, "Sum", typeof(Sum));
return 0;
}
else
{
return 1;
}
}


整个调用流程比较简单,在C#调用C++写的Dll过程中,关键是参数类型的对应方面容易出错,C++中的数据类型和C#中还是有些区别的,比如char在C#中是两个字节,在C++是一个字节。在C++中使用了指针,在C#中同样需要使用IntPtr获取其指针地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: