C#调用C/C++ DLL 参数传递和回调函数的总结
Int型传入:
Dll端:
extern "C" __declspec(dllexport) int Add(int a, int b) { return a+b; } |
C#端:
[DllImport("aeClient2.0.dll", CallingConvention =CallingConvention.Cdecl)] public static extern unsafe int Add(int a, int b); |
Int型传入传出:
Dll端:
extern "C" __declspec(dllexport) int Add(int *a, int* b) { *a = 2; *b = 3; return add(2, 3); } |
C#端
[DllImport("aeClient2.0.dll", CallingConvention =CallingConvention.Cdecl)] public static extern unsafe int Add(int a, int b); |
String传入:
Dll端:
extern "C" __declspec(dllexport) BOOL sendMessage(char* msg) { CString str = msg; ::AfxMessageBox(str.GetBuffer(0)); return 3; } |
C#端:
[DllImport("aeClient1.1.dll", CallingConvention =CallingConvention.Cdecl)] public static extern int sendMessage(string msg);
string strin = "llqq哈t哈t哈t呵?呵?"; sendMessage(strin); |
String型传入传出:
Dll端:
extern "C" __declspec(dllexport) BOOL GetErrorMessage(char *szErrorMessage ) { CString str = szErrorMessage; AfxMessageBox(str); char tmp[] = "nm世界和平nmnm"; strcpy(szErrorMessage,tmp); return 3; } |
C#端:
[DllImport("aeClient1.1.dll", CallingConvention =CallingConvention.Cdecl)] public static extern int GetErrorMessage(StringBuilder msg);
StringBuilder buf = new StringBuilder(1024);//指定的buf大小必须大于传入的字符长度 buf.Append("abc中国人"); int outdata = GetErrorMessage(buf, 1); string strout = buf.ToString(); |
结构体传入:
Dll端:
class NET_INFO_STRUCT { public: DWORD nDurationTime; //持?续?时º¡À间? double nReceiveByte; //接¨®收º?字Á?节¨² double nSendByte; //发¤¡é送¨ª字Á?节¨² WORD word; char buf[200]; FILETIME time; }; extern "C" __declspec(dllexport) BOOL NetGetConnectDetail(NET_INFO_STRUCT lpNetInfo) { ::AfxMessageBox(lpNetInfo.buf); return 3; }
|
C#端
public struct FILETIME { public uint high; public uint low; } public struct NET_INFO_STRUCT { public uint nDurationTime; //持?续?时º¡À间? public double nReceiveByte; //接¨®收º?字Á?节¨² public double nSendByte; //发¤¡é送¨ª字Á?节¨² public ushort ush; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)] public string str; public FILETIME time; } ; [DllImport("aeClient1.1.dll", CallingConvention =CallingConvention.Cdecl)] public static extern unsafe int NetGetConnectDetail(NET_INFO_STRUCT lpNetInfo);
NET_INFO_STRUCT stru = new NET_INFO_STRUCT(); stru.nDurationTime = 8989; stru.nReceiveByte = 89.89; stru.nSendByte = 89.8900; stru.ush = 56; stru.str = "来来去去ypfisja"; stru.time.high = 24; stru.time.low = 17; NetGetConnectDetail(stru); |
结构体数组传出:
Dll端:
struct UIM_BOOK_STRUCT { int UimIndex; char szName[15]; char szPhone[21]; }; extern "C" __declspec(dllexport) int ReadUimAllBook(UIM_BOOK_STRUCT lpUimBookItem[],intnMaxArraySize) { lpUimBookItem[0].UimIndex = 345; strcpy(lpUimBookItem[0].szName , "dsd"); strcpy(lpUimBookItem[0].szPhone , "bbbb");
lpUimBookItem[1].UimIndex = 111; strcpy(lpUimBookItem[1].szName , "ddddd"); strcpy(lpUimBookItem[1].szPhone , "vvvvvv");
lpUimBookItem[2].UimIndex = 2222; strcpy(lpUimBookItem[2].szName , "d3343434sd"); strcpy(lpUimBookItem[2].szPhone , "bbbfggfggggfgb");
return 4; } |
C#端:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct UIM_BOOK_STRUCT { public int UimIndex; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)] public string szName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] public string szPhone; }; [DllImport("aeClient1.1.dll", CallingConvention =CallingConvention.Cdecl)] public static extern unsafe int ReadUimAllBook([Out] UIM_BOOK_STRUCT[] lpUimBookItem, intnMaxArraySize);
UIM_BOOK_STRUCT[] p = new UIM_BOOK_STRUCT[20]; int rets = ReadUimAllBook(p, p.Length); |
回调函数传递字符串:
Dll端:
typedef int (*pfCallBack)(int a, char b[]); pfCallBack CallBackfun = NULL;
extern "C" __declspec(dllexport) void SetCB(int (*pfCallBack)(int a, charb[])) { CallBackfun = pfCallBack; } char ch[100]; extern "C" __declspec(dllexport) void callTheCB() { int a = 4; memset(ch, '\0', 100); strcpy(ch, "aabbcc"); CallBackfun(a, ch); } |
C#端
//定¡§义°?一°?个?委¡¥托ªD,ê?其?返¤¦Ì回?类¤¨¤型¨ª和¨ª形?参?与®?方¤?法¤¡§体¬?的Ì?返¤¦Ì回?类¤¨¤型¨ª形?参?一°?致? [UnmanagedFunctionPointer(CallingConvention.Cdecl)]//一°?定¡§要°a加¨®上¦?这a句?,ê?要°a不?然¨?C#中D的Ì?回?调Ì¡Â函¡¥数ºy只?要°a被À?调Ì¡Â用®?一°?次ä?,ê?程¨¬序¨°就¨ª异°¨¬常¡ê退ª?出?了¢?!ê?!ê?!ê? public delegate int callBackHandler(int a, [MarshalAs(UnmanagedType.LPStr)]StringBuilder b); callBackHandler fun;//声¦¨´明¡Â一°?个?委¡¥托ªD变À?量¢? [DllImport("xxx.dll", CallingConvention =CallingConvention.Cdecl)] public static extern unsafe void SetCB(callBackHandler fun1); [DllImport("xxx.dll", CallingConvention =CallingConvention.Cdecl)] public static extern unsafe void callTheCB();
int localFun(int a, [MarshalAs(UnmanagedType.LPStr)]StringBuilder b) { MessageBox.Show(b.ToString()); return 0; }
fun = new callBackHandler(localFun);//给?委¡¥托ªD变À?量¢?赋3值¦Ì SetCB(fun);//用®?委¡¥托ªD当Ì¡À做Á?函¡¥数ºy指?针?作Á¡Â为a参?数ºy传ä?入¨? callTheCB(); |
回调函数传递结构体:
Dll端:
struct REvent { REvent(ONEVENTSTRUCT* pEVENTSTRUCT); WORD m_ChangeMask; WORD m_State; char m_Source[200]; };
typedef void (*pfCallBackEvent)(REvent eve/*, char m_Source[]*/); pfCallBackEvent CallBackfunEvent = NULL; extern "C" __declspec(dllexport) void SetCBEvent(void (*pfCallBackEvent)(REvent eve/*, char m_Source[]*/)) { CallBackfunEvent = pfCallBackEvent; } void callCBEvent(REvent eve/*, char m_Source[]*/) { CallBackfunEvent(eve/*, m_Source*/); }
//调用回调函数 callCBEvent(*pREvent/*, pEvent->m_Message.GetBuffer(0)*/); |
C#端:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct REvent { public ushort m_ChangeMask; public ushort m_State; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)] public string m_Source; };
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]//可¨¦以°?指?定¡§编À¨¤码?类¤¨¤型¨ª public struct EventSourceTag { //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)] public IntPtr name; }; //定¡§义°?一°?个?委¡¥托ªD,ê?其?返¤¦Ì回?类¤¨¤型¨ª和¨ª形?参?与®?方¤?法¤¡§体¬?的Ì?返¤¦Ì回?类¤¨¤型¨ª形?参?一°?致? [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]//一°?定¡§要°a加¨®上¦?这a句?,ê?要°a不?然¨?C#中D的Ì?回?调Ì¡Â函¡¥数ºy只?要°a被À?调Ì¡Â用®?一°?次ä?,ê?程¨¬序¨°就¨ª异°¨¬常¡ê退ª?出?了¢?!ê?!ê?!ê? public delegate void CBEventHandle(REvent eve/*, [MarshalAs(UnmanagedType.LPStr)]StringBuilder source*/); CBEventHandle cbFun;//声¦¨´明¡Â一°?个?委¡¥托ªD变À?量¢? [DllImport("xxx.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern unsafe void SetCBEvent(CBEventHandle fun);
void CBEvent(REvent eve/*, [MarshalAs(UnmanagedType.LPStr)]StringBuilder source*/) { //string str = Marshal.PtrToStringAnsi(source); //string str = System.Text.Encoding.Default.GetString(source); MessageBox.Show(eve.m_Message.ToString()); }
cbFun = new CBEventHandle(CBEvent); SetCBEvent(cbFun); |

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java类加载机制,这篇大概、也许、可能就够了
写在前面 关于Java类加载机制一至有没办法说的痛苦。因为当初我在学习这方面的内容时,多多少少有一些懵逼,所以这次的文章,将尽可能的把概念性的东西转化成容易理解的内容,所以希望各位看到文章的童鞋可以有所收获~ 正文开始 第一步,先让咱们看一段代码: public class Main { static{ System.out.println("我是静态代码块"); } { System.out.println("我是实例代码块"); } public static void main(String[] args) { Main main1=new Main(); Main main2=new Main(); } } 各位小伙伴,这段代码run起来之后会是什么样的结构?这里就不卖关子了,直接贴结果。 image OK,如果小伙伴们,知道这个结果,并且也理解这个结果,那么接下来的内容就可以跳过啦。如果有疑问的话,那就让我们带着这个答案,往下看,内容很少,。重在理解~ Java类加载机制 先看一下概念 虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形...
- 下一篇
C#调用带结构体指针的C Dll的方法
原文: C#调用带结构体指针的C Dll的方法 在C#中调用C(C++)类的DLL的时候,有时候C的接口函数包含很多参数,而且有的时候这些参数有可能是个结构体,而且有可能是结构体指针,那么在C#到底该如何安全的调用这样的DLL接口函数呢?本文将详细介绍如何调用各种参数的方法。 一、调用接口仅含普通变量 eg:int fnAdd(int num1,int num2); 那么在C#调用这种函数最简单了,直接用函数原型即可,如下: [DllImport("你的dll名称", EntryPoint = "fnAdd", CallingConvention = CallingConvention.Cdecl)] public static extern int fnAdd(int num1, int num2); 这样在C#的方法内可以放心的使用这个dll函数了。 二、调用接口含普通变量的指针 大家都知道C#为了安全起见,隐形的避开了指针(其实在C#完全可以使用指针的,只是为了安全),采用了引用的方式来取代指针,引用的好处就是可以和指针一样操作参数原地址内的数据,并且这些数据在调用函数返回时还存...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Linux系统CentOS6、CentOS7手动修改IP地址
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Windows10,CentOS7,CentOS8安装Nodejs环境
- 设置Eclipse缩进为4个空格,增强代码规范