C++编写标准Win32DLL如下
头文件
源代码
C#写的测试代码如下
头文件
/*************************************************************************************************/
/*!
\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).