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

简介: 原文:C#调用C/C++ DLL 参数传递和回调函数的总结 Int型传入: Dll端: extern "C" __declspec(dllexport) int Add(int a, int b) ...
原文: C#调用C/C++ DLL 参数传递和回调函数的总结

Int型传入:

Dll端:

extern "C" __declspec(dllexportint Add(int aint b)

{

    return a+b;

}

C#端:

[DllImport("aeClient2.0.dll"CallingConvention =CallingConvention.Cdecl)]

 public static extern unsafe int Add(int aint b);

 

Int型传入传出:

Dll端:

extern "C" __declspec(dllexportint Add(int *aintb)

{

    *a = 2;

    *b = 3;

    return add(2, 3);

}

C#端

[DllImport("aeClient2.0.dll"CallingConvention =CallingConvention.Cdecl)]

 public static extern unsafe int Add(int aint b);

 

String传入:

Dll端:

extern "C" __declspec(dllexportBOOL sendMessage(charmsg)

{

    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 = "llqqttt??";

sendMessage(strin);

 

String型传入传出:

Dll端:

extern "C" __declspec(dllexportBOOL 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(dllexportBOOL 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(dllexportint 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([OutUIM_BOOK_STRUCT[] lpUimBookItemintnMaxArraySize);

 

UIM_BOOK_STRUCT[] p = new UIM_BOOK_STRUCT[20];

int rets = ReadUimAllBook(pp.Length);

 

回调函数传递字符串:

Dll端:

typedef int (*pfCallBack)(int achar b[]);

pfCallBack CallBackfun = NULL;

 

extern "C" __declspec(dllexportvoid SetCB(int (*pfCallBack)(int acharb[])) 

    CallBackfun = pfCallBack

char ch[100];

extern "C" __declspec(dllexportvoid callTheCB()

{

    int a = 4;

    memset(ch'\0', 100);

    strcpy(ch"aabbcc");

    CallBackfun(ach);

}

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(ONEVENTSTRUCTpEVENTSTRUCT);

    WORD    m_ChangeMask;

    WORD    m_State;

    char m_Source[200];

};

 

typedef void (*pfCallBackEvent)(REvent eve/*, char m_Source[]*/);

pfCallBackEvent CallBackfunEvent = NULL;

extern "C" __declspec(dllexportvoid 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);


目录
相关文章
|
6月前
|
C++ 数据格式
LabVIEW传递接收C/C++DLL指针
LabVIEW传递接收C/C++DLL指针
190 1
|
2月前
|
物联网 C# C语言
物联网开发中C、C++和C#哪个更好用
在物联网(IoT)开发中,C、C++和C#各有优缺点,适用场景不同。C语言性能高、资源占用低,适合内存和计算能力有限的嵌入式系统,但开发复杂度高,易出错。C++支持面向对象编程,性能优秀,适用于复杂应用,但学习曲线陡峭,编译时间长。C#易于学习,与.NET框架结合紧密,适合快速开发Windows应用,但性能略低,平台支持有限。选择语言需根据具体项目需求、复杂性和团队技术栈综合考虑。
|
1月前
|
C#
C#的方法的参数传递
C#的方法的参数传递
15 0
|
1月前
|
C#
Delphi可不可以制作出像c#那样的dll类库?
在Delphi中,创建DLL项目(如dll.dpr)并定义一个类TMyCls后,在另一个项目(如test.dpr)中可以引入此DLL并直接实例化和调用类的方法。然而,Delphi目前主要支持两种DLL形式:动态链接库(需显式声明exports,仅支持函数调用)和ActiveX DLL(需定义IDL接口)。这两种方式都较为繁琐。相比之下,C# 的DLL类库更为便捷,编写并编译后即可在其他项目中直接使用。
|
3月前
|
存储 C++
C++ dll 传 string 类 问题
C++ dll 传 string 类 问题
26 0
|
4月前
|
存储 C++ 运维
开发与运维函数问题之使用C++标准库中的std::function来简化回调函数的使用如何解决
开发与运维函数问题之使用C++标准库中的std::function来简化回调函数的使用如何解决
52 6
|
3月前
|
C#
C# WPF 将第三方DLL嵌入 exe
C# WPF 将第三方DLL嵌入 exe
77 0
|
3月前
|
C# 图形学 数据安全/隐私保护
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
|
5月前
|
Java Go C#
编程语言C#、C++、Java、Python、go 选择哪个好?
我想说的是,不论选择哪种编程语言,决定选择的都是你最终的目的,做选择之前,先充分调研每一个选择项,再做选择思路就会非常清晰了。
118 3
|
5月前
|
安全 编译器 API
程序与技术分享:C#调用DLL的几种方法
程序与技术分享:C#调用DLL的几种方法
81 0