原文: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.ByValTStrSizeConst =
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.SequentialCharSet = CharSet.Ansi)]

public struct UIM_BOOK_STRUCT

{

        public int UimIndex;

        [MarshalAs(UnmanagedType.ByValTStrSizeConst =
15)]

        public string szName;

        [MarshalAs(UnmanagedType.ByValTStrSizeConst =
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.SequentialCharSet = CharSet.Ansi)]

        public struct REvent

        {

            public ushort m_ChangeMask;

            public ushort m_State;

            [MarshalAs(UnmanagedType.ByValTStrSizeConst =
200)]

            public string m_Source;

        };

 

        [StructLayout(LayoutKind.SequentialCharSet = CharSet.Ansi)]//可¨¦以°?指?定¡§编À¨¤码?类¤¨¤型¨ª

        public struct EventSourceTag

        {

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

        public IntPtr name;

        };

        //定¡§义°?一°?个?委¡¥托ªD,ê?其?返¤¦Ì回?类¤¨¤型¨ª和¨ª形?参?与®?方¤?法¤¡§体¬?的Ì?返¤¦Ì回?类¤¨¤型¨ª形?参?一°?致? 

        [UnmanagedFunctionPointer(CallingConvention.CdeclCharSet = 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.AnsiCallingConvention = 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);

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

  1. vc调用BCB的dll 参数传递 报错

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

  2. Ajax前台调用后台方法、AJAX Pro2(回调函数)

    //获取分店 function cityResult() { if (cityName != "") { $("#ddlcity_").find("o ...

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

    dll 与 exe 之间的通讯方式有很多种, 本文采用回调函数的方法实现, 本文也将研究多线程,多模块的情况下,回调函数所在的线程, 啥也不说了,先附上代码: 下面的是dll模块的的, dll的工程文 ...

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

    什么是回调函数(callback)    模块A有一个函数foo,他向模块B传递foo的地址,然后在B里面发生某种事件(event)时,通过从A里面传递过来的foo的地址调用foo,通知A发生了什么事 ...

  5. [转]C++回调函数(callback)的使用

    原文地址:http://blog.sina.com.cn/s/blog_6568e7880100p77y.html 什么是回调函数(callback)    模块A有一个函数foo,他向模块B传递fo ...

  6. 理解 JavaScript 回调函数并使用

    JavaScript中,函数是一等(first-class)对象:也就是说,函数是 Object 类型并且可以像其他一等对象(String,Array,Number等)一样使用.它们可以"保 ...

  7. javascript 函数初探 (四)--- 回调函数

    回调函数 既然函数与任何被赋值给变量的数据是相同的,那么她当然可以像其他数据那样被定义.删除.拷贝,以及当成参数传递给其它函数. 我们定义一个函数,这个函数有两个函数类型的参数,然后他会分别执行这两个 ...

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

    理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报  分类: JavaScript(4)    目录( ...

  9. 理解 JS 回调函数中的 this

    任何变量或对象都有其赖以生存的上下文.如果简单地将对象理解为一段代码,那么对象处在不同的上下文,这段代码也会执行出不同的结果. 例如,我们定义一个函数 getUrl 和一个对象 pseudoWindo ...

随机推荐

  1. nginx源代码分析--ngx_http_optimize_servers()函数

    这个函数做了连部分工作:1)以port为入口点 将实用的信息存放到hash表内 2)调用ngx_http_init_listening()函数 对port进行监听 1. 在ngx_http_core_ ...

  2. 不使用left-join等多表关联查询,只用单表查询和Java程序,简便实现“多表查询”效果

    上次我们提到,不使用left-loin关联查询,可能是为了提高效率或者配置缓存,也可以简化一下sql语句的编写.只写单表查询,sql真得太简单了.问题是,查询多个表的数据还是非常需要的. 因此,存在这 ...

  3. 非常实用全面的 C++框架,库类等资源

    这次的资源涉及到了标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等,C++程序员学习必备! Jason frozen : C/C++的Jason解析生成器 Jansson ...

  4. js进阶 10-3 jquery中为什么用document.ready方法

    js进阶 10-3  jquery中为什么用document.ready方法 一.总结 一句话总结: 1.document.ready和window.onload的区别:用哪个好? document. ...

  5. 【30.00%】【vijos 1909】寻找道路

    描述 在有向图 G 中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到 终点的路径,该路径满足以下条件: 路径上的所有点的出边所指向的点都直接或间接与终点连通. 在满足条件 1 的情 ...

  6. 给博客签上CC协议

    大家都知道开源软件.通过开放源代码的方式,允许用户学习.修改.增进提高这些软件质量.软件界的开源协议很多,比如常见的 Apache,BSD,GPL 等等.这是一种充分利用网络的便利性,鼓励分享和创新的 ...

  7. Hibernate综合问题

    n + 1问题 query.iterate()信息返回迭代查询将开始发表声明:录ID语句 Hibernate: select student0_.id ascol_0_0_from t_student ...

  8. 半监督学习(semi-supervised learning)

    P(x)P(x,y)}⇒P(y|x) 自 P(x) 生成的无标签样本: 自 P(x,y) 生成的标记样本:

  9. 线性滤波器(linear filter)与非线性滤波器(non-linear filter)

    1. 均值滤波器与中值滤波器 image processing - Difference between linear and non linear filter - Signal Processin ...

  10. Codeforces Round #248 (Div. 2) B称号 【数据结构:树状数组】

    主题链接:http://codeforces.com/contest/433/problem/B 题目大意:给n(1 ≤ n ≤ 105)个数据(1 ≤ vi ≤ 109),当中有m(1 ≤ m ≤  ...