C#调用C/C++ DLL 参数传递和回调函数的总结

原文: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;?//持?续?时o?à间???

????double?nReceiveByte;?//接¨?收o?字á?节¨2?

????double?nSendByte;???//发¤?é送¨a字á?节¨2?

????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;?//持?续?时o?à间???

????????public?double?nReceiveByte;?//接¨?收o?字á?节¨2?

????????public?double?nSendByte;???//发¤?é送¨a字á?节¨2?

????????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#端


//定?§义°?一°?个?委?¥托aD,ê?其?返¤|ì回?类¤¨¤型¨a和¨a形?参?与??方¤?法¤?§体??的ì?返¤|ì回?类¤¨¤型¨a形?参?一°?致??

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]//一°?定?§要°a加¨?上|?这a句?,ê?要°a不?然¨?C#中D的ì?回?调ì??函?¥数oy只?要°a被à?调ì??用??一°?次??,ê?程¨?序¨°就¨a异°¨?常?ê退a?出?了¢?!ê?!ê?!ê??

public?delegate?int?callBackHandler(int?a,
[MarshalAs(UnmanagedType.LPStr)]StringBuilder?b);

callBackHandler?fun;//声|¨′明??一°?个?委?¥托aD变à?量¢??

[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);//给?委?¥托aD变à?量¢?赋3值|ì???

SetCB(fun);//用??委?¥托aD当ì?à做á?函?¥数oy指?针?作á??为a参?数oy传??入¨?

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)]//可¨|以°?指?定?§编ਤ码?类¤¨¤型¨a

????????public?struct?EventSourceTag

????????{

????????????//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)]

????????public?IntPtr?name;

????????};

????????//定?§义°?一°?个?委?¥托aD,ê?其?返¤|ì回?类¤¨¤型¨a和¨a形?参?与??方¤?法¤?§体??的ì?返¤|ì回?类¤¨¤型¨a形?参?一°?致??

????????[UnmanagedFunctionPointer(CallingConvention.Cdecl,?CharSet?=?CharSet.Ansi)]//一°?定?§要°a加¨?上|?这a句?,ê?要°a不?然¨?C#中D的ì?回?调ì??函?¥数oy只?要°a被à?调ì??用??一°?次??,ê?程¨?序¨°就¨a异°¨?常?ê退a?出?了¢?!ê?!ê?!ê?

????????public?delegate?void?CBEventHandle(REvent?eve/*,
[MarshalAs(UnmanagedType.LPStr)]StringBuilder source*/);

????????CBEventHandle?cbFun;//声|¨′明??一°?个?委?¥托aD变à?量¢??

????????[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);

原文地址:https://www.cnblogs.com/lonelyxmas/p/9388795.html

时间: 2024-08-28 13:24:59

C#调用C/C++ DLL 参数传递和回调函数的总结的相关文章

vc调用delphi的dll 参数传递 报错

可能原因: 调用方式约定不一致. 函数调用约定如下: 1. __cdecl:C 和 C++ 程序的缺省调用规范. 2. __stdcall:标准调用约定(即WINAPI调用约定),也就是pascal调用约定. 如果VC调用时,调用的约定方式和delphi的dll中函数约定方式不一致,就会出问题.

DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间

dll 与 exe 之间的通讯方式有很多种, 本文采用回调函数的方法实现, 本文也将研究多线程,多模块的情况下,回调函数所在的线程, 啥也不说了,先附上代码: 下面的是dll模块的的, dll的工程文件: [delphi] view plaincopy library DllAPP; uses windows, SysUtils, Classes, DllClass in 'DllClass.pas'; {$R *.res} var GDllServer: TDllServer; functio

回调函数,就是回头再调用的函数

又遇到了回调函数,这次打算写下来分享一下.水平有限,如有错误,请指正. 转载请注出处. 所谓回调函数,或者在面向对象语言里叫回调方法,简单点讲,就是回头在某个时间(事件发生)被调用的函数. 再详细点:就是一个函数A,作为参数,传入了另一个函数B,然后被B在某个时间调用. 这里可以有疑问了,既然是一个函数调用另一个函数,可以在函数体里面调用啊,为什么还要把函数作为参数传到另一个函数里被调用?何况还有一些语言(比如java)不支持把函数作为参数. 对的,确实可以在函数体里调用另一个函数,功能上好像是

回调函数中调用类中的非静态成员变量或非静态成员函数

有关这方面的问题,首先说一点: 回调函数必须是静态成员函数或者全局函数来实现回调函数,大概原因是普通的C++成员函数都隐含了一个函数参数,即this指针,C++通过传递this指针给成员函数从而实现函数可以访问类的特定对象的数据成员.由于this指针的原因,使得一个普通成员函数作为回调函数时就会因为隐含的this指针问题使得函数参数个数不匹配,从而导致回调函数编译失败. 基于上面的理论,如何在类中封装回调函数呢? 回调函数只能是全局函数或者静态成员函数,但是由于全局函数会破坏封装性,所以只能用静

c回调函数(真不好理解)

什么是回调函数(callback) 模块A有一个函数foo,它向模块B传递foo的地址,然后在B里面发生某种事件(event)时,通过从A里面传递过来的foo的地址调用foo,通知A发生了什么事情,让A作出相应反应. 那么我们就把foo称为回调函数. 例子: 回调函数是一个很有用,也很重要的概念.当发生某种事件时,系统或其他函数将会自动调用你定义的一段函数.回调函数在windows编程使用的场合很多, 比如Hook回调函数:MouseProc,GetMsgProc以及EnumWindows,Dr

C++回调函数(callback)的使用

什么是回调函数(callback)    模块A有一个函数foo,他向模块B传递foo的地址,然后在B里面发生某种事件(event)时,通过从A里面传递过来的foo的地址调用foo,通知A发生了什么事情,让A作出相应反应. 那么我们就把foo称为回调函数.   例子:      回调函数是个很有用,也很重要的概念.当发生某种事件时,系统或其他函数将会自动调用您定义的一段函数.回调函数在windows编程使用的场合很多, 比如Hook回调函数:MouseProc,GetMsgProc连同EnumW

JavaScript中的回调函数

在学习JavaScript的过程中遇到了很多,使用到回调函数的例子,出现了许多疑问,就由一个栗子开始吧: 在JavaScript中接触的第一个回调函数是在setInterval()和setTimeout()中出现的: 1 var num = 10; 2 3 var interValId = setInterval(function (){ 4 console.log(num); 5 num--; 6 if(num==0){ 7 clearInterval(interValId); 8 } 9 }

JavaScript之callback回调函数

以下内容借鉴老鸟的经验和知识,结合自己的学习,精髓的总结. 一句话:对于以后研究node 和那些热门的前端框架 很有帮助.如果你看过这个文章,对于你来说是质的突变. 理解javascript中的回调函数(`callback`),希望对你有所帮助. 在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,和其它String.Array.Number.Object类的对象一样用于内置对象的管理. function实际上是一种对象,它可以"存储在变量中,通过参数传递给(别一

理解和使用 JavaScript 中的回调函数

原文:http://javascriptissexy.com/ 在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实际上是一种对象,它可以"存储在变量中,通过参数传递给(别一个)函数(function),在函数内部创建,从函数中返回结果值". 因为function是内置对象,我们可以将它作为参数传递给另一个函数,延迟到函数中执行,甚至执行后