`

C#使用C++标准DLL实例(包含callback)

 
阅读更多
C++编写标准Win32DLL如下

头文件
/*************************************************************************************************/
/*!
    \file CppDll.h

    \attention
        Copyright (c) 2016  Jacky_Dai.
        All Rights Reserved.
*/
/*************************************************************************************************/
#ifndef CPP_DLL_H
#define CPP_DLL_H

/*** Defines/Macros/Constants/Typedefs ***********************************************************/
#ifdef CPPDLL_EXPORTS
#define CPPDLL_API __declspec(dllexport)
#else
#define CPPDLL_API __declspec(dllimport)
#endif

//Include Head files
//////////////////////////////////////////////////////////////////////////
#include <Windows.h>



#ifdef __cplusplus
extern "C"
{
#endif

/*************************************************************************************************/
/*!
    \brief CPP_CALLBACK 
    The callback for test.

    Note: Out put test data

    \param[out]  pbySignatureData - Reserved buffer for writing signature.
    \param[in/out]  pdwSignatureDataSize - The reserved data size / Used data size

    \return  Return ERR_OK if the function succeeds else nonzero error code.
*/
/*************************************************************************************************/
typedef DWORD (CALLBACK *CPP_CALLBACK)(PBYTE pbySignatureData, DWORD pdwSignatureDataSize);

CPPDLL_API DWORD TestApp1(BYTE* pByInBuffer,
                               DWORD dwInSize,
                               BYTE* pByOutBuffer,
                               DWORD* pdwOutSize);

CPPDLL_API DWORD TestApp2(BYTE* pByInBuffer,
                                DWORD dwInSize,
                                BYTE* pByOutBuffer,
                                DWORD* pdwOutSize,
                                CPP_CALLBACK pCallback);

CPPDLL_API DWORD TestApp3(DWORD dwVal);

CPPDLL_API DWORD TestApp4(DWORD* pdwVal);

#ifdef __cplusplus
}
#endif

#endif//CPP_DLL_H



源代码
#include "CppDll.h"
#include "stdio.h"
#include <string.h>
#include <time.h>

DWORD TestApp1(BYTE* pByInBuffer,
                   DWORD dwInSize,
                   BYTE* pByOutBuffer,
                   DWORD* pdwOutSize)
{
    if (pByOutBuffer!=NULL && pdwOutSize != NULL)
    {
        CHAR szTemp[1024] = {0};
        sprintf(szTemp, "[CppDll][%s] catch en error in line(%d).\r\n", __FUNCTION__, __LINE__);

        if (*pdwOutSize >= strlen(szTemp))
        {
            *pdwOutSize = (DWORD)strlen(szTemp);
            memcpy(pByOutBuffer, szTemp, strlen(szTemp));
        }
        else
        {
            *pdwOutSize = 0;
        }
    }

    return 0x0201;
}


DWORD TestApp2(BYTE* pByInBuffer,
                   DWORD dwInSize,
                   BYTE* pByOutBuffer,
                   DWORD* pdwOutSize,
                   CPP_CALLBACK pCallback)
{
    if (pByOutBuffer!=NULL && pdwOutSize != NULL)
    {
        CHAR szTemp[1024] = {0};
        sprintf(szTemp, "[CppDll][%s] catch en error in line(%d).\r\n", __FUNCTION__, __LINE__);

        if (*pdwOutSize >= strlen(szTemp))
        {
            *pdwOutSize = (DWORD)strlen(szTemp);
            memcpy(pByOutBuffer, szTemp, strlen(szTemp));

            if (pCallback != NULL)
            {
                CHAR szCallbackTemp[1024] = {0};
                sprintf(szCallbackTemp, "[CppDll][%s] Callback output data in line(%d).\r\n", __FUNCTION__, __LINE__);

                pCallback((PBYTE)(szCallbackTemp), (DWORD)strlen(szCallbackTemp));
            }
        }
        else
        {
            *pdwOutSize = 0;
        }
    }

    Sleep(500);
    return 0x0205;
}

CPPDLL_API DWORD TestApp3(DWORD dwVal)
{
    if (0 == dwVal)
    {
        return 0;
    }

    return 1;
}

CPPDLL_API DWORD TestApp4(DWORD* pdwVal)
{
    if (NULL != pdwVal)
    {
        *pdwVal = 256;
        return 0;
    }

    return 1;
}



C#写的测试代码如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;//DllImport
using System.Diagnostics;//Debug

namespace CSharpUsingCppCallbackDemo
{
    public partial class Form1 : Form
    {
        public delegate uint CppCallback([MarshalAs(UnmanagedType.LPArray, SizeConst = 1024)]byte[] byOutBuffer, uint outSize);


        private const string testDll = @"C:\Users\jacky_dai\Desktop\CSharpUsingCppCallbackDemo\Debug\CppDll.dll";

        [DllImport(testDll)]
        public static extern uint TestApp1([In]byte[] inBuffer, [In]uint inSize, [In][Out]byte[] byOutBuffer, [In][Out]ref uint outSize);

        [DllImport(testDll)]
        public static extern uint TestApp2([In]byte[] inBuffer, [In]uint inSize, [In][Out]byte[] byOutBuffer, [In][Out]ref uint outSize, CppCallback pCallback);

        [DllImport(testDll)]
        public static extern uint TestApp3([In]uint dwVal);

        [DllImport(testDll)]
        public static extern uint TestApp4([In][Out]ref uint dwVal);


        public Form1()
        {
            InitializeComponent();
        }

        public uint TestCallback(/*[MarshalAs(UnmanagedType.LPArray, SizeConst=1024)]*/byte[] byOutBuffer, uint outSize)
        {

            string strMsg = System.Text.Encoding.Default.GetString(byOutBuffer);
            Debug.WriteLine(strMsg);

            return 0;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            uint ret = 0;
            byte[] helloBuf = new byte[2048];
            byte[] tempbuffer = new byte[2048];
            uint bufSize = 2048;

            //ret = TestApp3(bufSize);
            //ret = TestApp4(ref bufSize);

            //ret = TestApp1(helloBuf, ret, tempbuffer, ref bufSize);

            ret = TestApp2(helloBuf, ret, tempbuffer, ref bufSize, new CppCallback(TestCallback));

            string strMsg = System.Text.Encoding.Default.GetString(tempbuffer);
            Debug.WriteLine(strMsg);
        }
    }
}



[CppDll][TestApp2] Callback output data in line(50).
[CppDll][TestApp2] catch en error in line(40).
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics