C#调用C++DLL,及回调函数、string参数传递的总结

1 篇文章 0 订阅
1 篇文章 0 订阅

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

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[],int nMaxArraySize)

{

    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, int nMaxArraySize);

 

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, char b[])) 

{ 

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

 

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#调用 C++ DLL 函数的时候,如果函数的参数是 std::string 类型,需要进行一些特殊的处理。因为在 C++ 中,std::string 类型实际上是一个类,而在 C# 中没有对应的类型。 一种解决方案是,将 C++ 函数参数中的 std::string 类型改为 char* 类型,并且增加参数来指定字符串的长度。在 C# 中,可以使用 Marshal 类的各种方法来将字符串转换为 char* 类型,并将字符串的长度传递给 C++ 函数。 下面是一个示例代码,演示了如何在 C#调用一个 C++ DLL 函数,该函数的参数类型为 std::stringC++ DLL 函数的代码: ```c++ #include <string> #include <iostream> // 定义一个使用 std::string 作为参数的函数 void printString(std::string str) { std::cout << str << std::endl; } ``` 在 C#调用该函数的代码: ```c# using System; using System.Runtime.InteropServices; class Program { // 声明 C++ DLL 函数 [DllImport("MyCppLib.dll", CallingConvention = CallingConvention.Cdecl)] static extern void printString([MarshalAs(UnmanagedType.LPStr)] string str, int length); static void Main(string[] args) { // 要传递给 C++ DLL 函数的字符串 string myString = "Hello, world!"; // 将字符串转换为 char* 类型,并获取字符串的长度 byte[] strBytes = System.Text.Encoding.ASCII.GetBytes(myString); int strLength = strBytes.Length; // 调用 C++ DLL 函数 printString(myString, strLength); } } ``` 在 C# 中,使用 [MarshalAs(UnmanagedType.LPStr)] 特性将 C++ 函数参数中的 std::string 类型转换为 char* 类型,使用 System.Text.Encoding.ASCII.GetBytes() 方法将字符串转换为 byte[] 类型,并使用该数组的长度作为字符串的长度参数传递C++ 函数。 希望这个示例代码对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值