您的位置:首页 > 编程语言 > C语言/C++

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

2017-12-29 15:01 218 查看
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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: