本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1. vs2010 新建项目 / Visual C++ / 类库; 项目名 MyCallbackDll
头文件:
定义类 成员函数
\
// MyCallbackDll.h
#pragma once
using namespace System;
#ifdef DLL
#define DLL_API __declspec(dllexport)
#else
#define DLL_API
#endif
namespace MyCallbackDll
{
public DLL_API class ClassDll
{
// TODO: 在此处添加此类的方法。
public:
int Add(int a,int b);
//{
// return a + b;
//}
};
}
开放函数接口
#include "StdAfx.h"
//#include "MyCallbackDll.h"
using namespace MyCallbackDll;
typedef int (*Operate)(int a, int b); //函数指针, 回调C#函数, 传入参数 传出结果
static Operate pOptFun; //
extern "C" __declspec(dllexport) int ExportAdd(int x,int y);
//注册回调
extern "C" __declspec(dllexport) void RegistCallback(Operate opt);
//回调测试
extern "C" __declspec(dllexport) int TestOperateCallback(int x,int y);
//////////////////////////////////////////////////////////////////////////////////////
char* pStr = "very good!!!";
typedef int (*pFunOutputStr)(char* pOut); //函数指针, 回调C#函数,传出字符串
static pFunOutputStr pOutputFun;
//注册回调
extern "C" __declspec(dllexport) void RegistOutputStrCallback(pFunOutputStr opt);
//回调测试
extern "C" __declspec(dllexport) void TestOutputString();
源文件:
实现类成员函数
// 这是主 DLL 文件。
#include "stdafx.h"
#include "MyCallbackDll.h"
using namespace MyCallbackDll;
int ClassDll::Add(int a,int b)
{
return a + b;
}
对外接口实现:
#include "StdAfx.h"
#include "MyCallbackDll.h"
#include "ExportDll.h"
using namespace MyCallbackDll;
int ExportAdd(int x,int y)
{
ClassDll* pCDll;
return pCDll->Add(x,y);
}
//注册回调
void RegistCallback(Operate opt)
{
pOptFun = opt;
}
//回调测试
int TestOperateCallback(int x,int y)
{
return pOptFun(x, y);;
}
//////////////////////////////////////////////////////////////////////////////////////
//注册回调
void RegistOutputStrCallback(pFunOutputStr opt)
{
pOutputFun = opt;
}
//回调测试
void TestOutputString()
{
pOutputFun(pStr);
}
2. vs2010 新建项目 / Visual C# / 控制台应用程序; 项目名 TestMyCallbackDll
引入动态库 MyCallbackDll.dll
using System.Runtime.InteropServices;
namespace TestMyCallbackDll
{
class ImportDll
{
[DllImport("MyCallbackDll.dll", EntryPoint = "ExportAdd", CallingConvention = CallingConvention.Cdecl)]
public static extern int ExportAdd(int a, int b);
//测试回调
public delegate int OperateDelegate(int a, int b);
[DllImport("MyCallbackDll.dll", EntryPoint = "RegistCallback", CallingConvention = CallingConvention.Cdecl)]
public static extern void RegistCallback(OperateDelegate opeDelegate);
[DllImport("MyCallbackDll.dll", EntryPoint = "TestOperateCallback", CallingConvention = CallingConvention.Cdecl)]
public static extern int TestOperateCallback(int a, int b);
//回调 传字符串
public delegate void OutputStrDelegate(string str);
[DllImport("MyCallbackDll.dll", EntryPoint = "RegistOutputStrCallback", CallingConvention = CallingConvention.Cdecl)]
public static extern void RegistOutputStrCallback(OutputStrDelegate output);
[DllImport("MyCallbackDll.dll", EntryPoint = "TestOutputString", CallingConvention = CallingConvention.Cdecl)]
public static extern void TestOutputString();
}
}
调用Dll 函数接口,及回调测试:
using System;
namespace TestMyCallbackDll
{
class Program
{
//static bool bIsRun = true;
////public extern class ClassDll;
//static IntPtr pt;
static void Main(string[] args)
{
int iAddRet = ImportDll.ExportAdd(3, 7);
Console.WriteLine("{0} + {1} = {2}", 3, 7, iAddRet);
ImportDll.OperateDelegate od = new ImportDll.OperateDelegate(SubOperate);
ImportDll.RegistCallback(od);
int iCallbackRet = ImportDll.TestOperateCallback(5, 3);
Console.WriteLine("{0} - {1} = {2}", 5, 3, iCallbackRet);
ImportDll.OutputStrDelegate outputDelegate = new ImportDll.OutputStrDelegate(GetStringCallBack);
ImportDll.RegistOutputStrCallback(outputDelegate);
ImportDll.TestOutputString();
}
static string outputStr = null;
public static void GetStringCallBack(string strRet)
{
outputStr = strRet;
Console.WriteLine(outputStr);
Console.WriteLine("test good!!");
}
public static int SubOperate(int a, int b)
{
return a - b;
}
}
}