VS2019 C++的跨平台开发——C# WPF

本博客介绍了如何在VS2019中使用C++开发DLL,供C# WPF应用程序调用。内容包括C++的导出设置、C#接口封装类的实现,以及项目准备和效果展示。重点讨论了C++的导出限制和C#调用C++接口的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇介绍如何使用C++开发DLL给WPF的C#脚本调用。本文虽然以C#的WPF窗体应用为例子,但不限于此,.net平台都可以使用,包括Unity的C#脚本。


项目准备

首先VS2019相对于VS2017最明显的变化就是创建新建工程的界面,创建C++ DLL 工程和C# WPF如下图所示:

C++项目的配置就参考之前的文章https://blog.youkuaiyun.com/luoyu510183/article/details/83999548,下面就不详细说明了。C#的UI代码我也不说明,主要是讲C#调用C++ DLL的部分,其他部分可以下载我的工程看源码理解。

C++项目的提醒事项:


C++的导出设置

先看看C++项目的文件结构:

NativeInterface

先看下NativeIterface的代码,这个文件是把这个DLL下所有的导出接口都以一个类的形式进行导出。代码如下:

/////////////////////////////////////////////
////////////NativeInterface.h////////////////
/////////////////////////////////////////////
#pragma once

extern "C" {
	//本类把本DLL下的所有接口都统一在这里,使用单例的方式创建指针给C#使用
	//以下的成员函数皆为函数指针的形式,因为,类的函数实际上还有一个隐藏this的指针参数,
	//不便于C#解析。ITest1Manager这个类也举了怎么导出类的成员函数的例子。
	//注意下面的函数指针和函数都是_stdcall,这是微软的示例里面使用的默认调用方式,即
	//从右到左参数入栈,并且被调用方清理堆栈。这个是windows独有的,包括_thiscall,_clrcall,__cdecl等。
	//关注于Windows平台的需要好好理解,其他默认使用_stdcall就行
	class NativeManager
	{
	public:
		//字符串传递测试
		const char* (_stdcall *GetModuleName)();
		//设置回调函数测试
		void (_stdcall* SetLogHandler)(LogHandler handler);
		//导出其他类测试
		class CTestManager* TestManager;
		//测试成员变量,错误
		int Count;
		//正确的获取总数
		int (_stdcall *GetCount)();
		//非函数指针,虚函数导出测试
		class ITest1Manager* Test1Manager;

		NativeManager();
		~NativeManager();
	};
	//导出不能直接导出变量,所以用这个函数导出类的指针,用单例的方式创建
	_declspec(dllexport) NativeManager* _stdcall CreateNativeManager();
	//本函数用于释放导出类
	_declspec(dllexport) void _stdcall ReleaseNativeManager();
	//测试设置C#的回调函数
	_declspec(dllexport) void (_stdcall ExSetLogHandler)(LogHandler handler);
}
//测试不使用 extern "C"的导出函数名
_declspec(dllexport) void (_stdcall ReleaseNativeManager1)(int num);


/////////////////////////////////////////////
////////////NativeInterface.cpp//////////////
/////////////////////////////////////////////
#include "pch.h"
#include "NativeInterface.h"
#include "CTestManager.h"
static const char* name = "Name is Native Interface";
static NativeManager* Instance = nullptr;
static int NameCount = 0;
static const char* _stdcall SGetModuleName()
{
	//SafeLog 作为C++项目的日志打印,编译定义在pch.cpp中,整个工程全局可用。
	//调用的是C#的Log回调函数,打印字符串会通过C#回调函数显示在界面上
	Instance->Count = NameCount++;
	SafeLog("%s Count:%d", name,NameCount);
	return name;
}
static int _stdcall SGetCount()
{
	return NameCount;
}
//LogHandler 定义在pch.h中:typedef void (_stdcall * LogHandler)(const char*);
//__stdcall是Windows的回调函数的统一调用约定,被调用方清理堆栈
//
void (_stdcall ExSetLogHandler)(LogHandler handler)
{
	//Log定义在pch.cpp中,作为全局的Log函数指针
	Log =(handler);
}

static void (_stdcall SSetLogHandler)(LogHandler handler)
{
	char temp[256];
	sprintf_s(temp, "Log Handler %p", handler);
	Log = handler;
	SafeLog(temp);
}

NativeManager::NativeManager()
{
	SafeLog("NativeManager()");
	GetModuleName = SGetModuleName;
	SetLogHandler = SSetLogHandler;
	TestManager = new CTest
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值