C#调用C++动态链接库中的函数指针与函数指针结构

C#调用C++动态链接库中的函数指针与函数指针结构 [ http://www.dreamdu.com/blog/2008/04/25/cs_cpp_functionpointer/ ] ...

C#调用C++动态链接库中的函数指针与函数指针结构

这几天做项目时,遇到了 C#调用C++函数指针 的问题,C#调用C++ dll中的函数很简单,函数指针还真没调过,看了几篇文章研究了会儿后把问题搞定了,这里总结一下。

先看两篇文章:

http://jc.nfxxw.com/n/200607/14/n20060714_19510.shtml C#中的函数指针 (实在是找不到出处了)

http://dev.csdn.net/article/69/69261.shtm 如何在C#中使用 Win32和其他库 (这篇我在msdn上找了半天也没找到!)

函数指针搞C++的人应该都知道,效率高,易用性强,隐蔽代码等。在C++里面调用C++写的dll的函数指针那是在容易不过了。使用C#就稍微麻烦点了!那怎么掉呢?通过上面的第一篇文章我们知道应该使用委托 delegate。如果再高级点,定义一个函数指针结构(有点像linux的内核),也同样可以用C#调用。

猴子提示:委托就和C++中的函数指针一样。

下面我只写出了.h和.cs文件,都是伪代码,大家如果能明白意思,可以很简单的用到自己的项目了。

.h文件

// 获得梦之都网站的ip pDes  -  梦之都的网址 http://www.dreamdu.com/// 返回值 - false 获取失败 true 获取成功typedef bool (*Dreamdu_PGetIP)(char const* pDes) ; // 获得可爱的猴子的名字 pDes  -  可爱的猴子的名字 http://www.dreamdu.com/blog/// 返回值 - false 获取失败 true 获取成功typedef void (*Monkey_PGetName)(char const* pDes) ; // 梦之都的函数指针结构struct Dreamdu_Struct{Dreamdu_PGetIPDreamdu_GetIP;Monkey_PGetName Monkey_GetName;} ;// 获取梦之都的函数指针结构的函数指针// pDreamdu  -  梦之都的函数指针结构数组typedef void (*Dreamdu_PGetDreamduStruct)(Dreamdu_Struct *pDreamdu) ;// 获取梦之都函数指针结构的函数 这个就是输出函数啦 哈哈// pDreamdu  -  函数指针结构数组extern "C" Dreamdu_DLL_EXT_ void Dreamdu_GetDreamduStruct(Dreamdu_Struct *pDreamdu) ;

.csCS文件

public class Dreamdu{//加载dll[DllImport("kernel32.dll")]private static extern IntPtr LoadLibrary(string lpFileName); //获得函数指针的地址[DllImport("kernel32.dll")]private static extern GetDreamduFuns GetDreamduAddress(IntPtr hModule, string lpProcName);//释放dll[DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]private static extern bool FreeLibrary(IntPtr hModule);private delegate void GetDreamduFuns(IntPtr funs);private delegate bool Dreamdu_PGetIP(string name);private delegate void Monkey_PGetName(string name);//函数指针结构在cs中的声明[StructLayout(LayoutKind.Sequential, Pack = 1)]private class Dreamdu_Struct{public Dreamdu_PGetIP GetIP;public Monkey_PGetName GetName;}//装载 Dllpublic static void LoadDll(string lpFileName){hModule = LoadLibrary(lpFileName);if (hModule == IntPtr.Zero)throw (new Exception());}//获得函数指针public static void LoadFun(string lpProcName){if (hModule == IntPtr.Zero)throw (new Exception(""));dreamduStruct = GetProcAddress(hModule, lpProcName);if (farProc == null)throw (new Exception(""));try{pcon = Marshal.AllocHGlobal(Marshal.SizeOf(func));Marshal.StructureToPtr(func, pcon, true);dreamduStruct(pcon);Marshal.PtrToStructure(pcon, func);}finally{Marshal.FreeHGlobal(pcon);}}//卸载 Dllpublic static void UnLoadDll(){bool ret = FreeLibrary(hModule);hModule = IntPtr.Zero;dreamduStruct = null;}public static bool GetIP(string name){return func.Dreamdu_PGetIP(name);}public static void GetName(string name){return func.Monkey_PGetName(name);}private static IntPtr hModule = IntPtr.Zero;private static GetDreamduFuns dreamduStruct = null;private static FUNDreamduStruct func = new Dreamdu_Struct();private static IntPtr pcon = IntPtr.Zero;}

上面的C#接口就已经封装好了,仔细观察GetDreamduAddress函数kernel32.dll中此函数是返回FARPROC指针的,但是在这里我重新定义了一个委托来获取函数指针。

上面的C#接口就已经封装好了,可以使用下面方式调用。

class DreamduDLL{Dreamdu.LoadDll("Dreamdu.dll");Dreamdu.LoadFun("Dreamdu_GetDreamduStruct");//获取ipbool hasIP = Dreamdu.GetIP("www.dreamdu.com");if(hasIP){//获取名称Dreamdu.GetName("www.dreamdu.com/blog/");}//使用完了别忘了卸载dllDreamdu.UnLoadDll();}
...
CSharp 调用C++ DLL; 参数为指针类型导出函数 c# Csharp调用 c++库 参数为导入和导出指针两种 包含C++ DLL源码 如fun(cont char* A,char*B) A为输入参数,B为输出参数-C# CSharp call C++ DLL lib dll function param use export and import eg: fun(cont char* A,char*B) A IN,B OUT TestDll\Debug\TestCallDll.exe .......\.....\TestCallDll.vshost.exe .......\.....\TestCallDll.vshost.exe.manifest .......\.....\TestDll.dll .......\.....\TestDll.lib .......\TestCallDll\Form1.cs .......\...........\Form1.Designer.cs .......\...........\Form1.resx .......\...........\obj\Debug\TestCallDll.csproj.FileListAbsolute.txt .......\...........\...\.....\TestCallDll.csproj.GenerateResource.Cache .......\...........\...\.....\TestCallDll.exe .......\...........\...\.....\TestCallDll.Form1.resources .......\...........\...\.....\TestCallDll.pdb .......\...........\...\.....\TestCallDll.Properties.Resources.resources .......\...........\Program.cs .......\...........\...perties\AssemblyInfo.cs .......\...........\..........\Resources.Designer.cs .......\...........\..........\Resources.resx .......\...........\..........\Settings.Designer.cs .......\...........\..........\Settings.settings .......\...........\TestCallDll.csproj .......\....Dll\dllmain.cpp .......\.......\ReadMe.txt .......\.......\stdafx.cpp .......\.......\stdafx.h .......\.......\targetver.h .......\.......\TestDll.cpp .......\.......\TestDll.def .......\.......\TestDll.h .......\.......\TestDll.vcproj .......\.......\TestDll.vcproj.PC-201008261742.Administrator.user .......\TestDll.sln .......\TestDll.suo .......\....CallDll\obj\Debug\TempPE .......\...........\...\Debug .......\...........\obj .......\...........\Properties .......\Debug .......\TestCallDll .......\TestDll TestDll
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值