文号
822382
阅读
3831
回复
0
收藏
1
C++调用WPF
2016/07/07
IP:四川

对,不是C++/CLI。用的是.NET的非托管接口和反射特性。

优点是与编译器无关,缺点是比较麻烦,需要用反射进行调用。

<configuration>
  <startup uselegacyv2runtimeactivationpolicy="true">
    <supportedruntime version="v4.0.30319">
    <supportedruntime version="v2.0.50727">
  </supportedruntime></supportedruntime></startup>
</configuration>
// bindcoree.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#pragma warning(disable: 4996)

#include <windows.h>
#include <shlwapi.h>
#include <mscoree.h>
#import <mscorlib.tlb> rename("ReportEvent", "ReportEvent_mscor")
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "mscoree.lib")
using namespace mscorlib;

int _tmain(int argc, _TCHAR* argv[])
{
	// 初始化COM线程模型
	HRESULT hr = CoInitialize(NULL); // 重要!运行WinForms和WPF必需

	// 构造app.config路径
	WCHAR path[MAX_PATH];
	GetModuleFileName(NULL, path, MAX_PATH);
	PathRemoveFileSpec(path);
	PathAppend(path, L"app.config");
	
	// 初始化.NET运行库(没找到app.config按.NET2.0/3.x加载)
	ICorRuntimeHost *crh = NULL;
	hr = CorBindToCurrentRuntime(path, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void**)&crh);
	crh->Start();

	// 获取当前程序域
	IUnknownPtr domainunk;
	crh->CurrentDomain(&domainunk);
	_AppDomainPtr domain;
	domain = domainunk;
	
	// 加载WPF运行库程序集(只加载需要的就行了)
	// 注册程序集一般要强名称才能加载,可以去以下两个地方找到相关信息:
	// C:\Windows\assembly - .NET 2.0/3.x
	// C:\Windows\Microsoft.NET\assembly - .NET 4.x
	_AssemblyPtr prefx = domain->Load_2(_bstr_t(L"PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"));
	//_AssemblyPtr precore = domain->Load_2(_bstr_t(L"PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"));
	//_AssemblyPtr winbase = domain->Load_2(_bstr_t(L"WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"));
	
	// 获取Window类型信息
	_TypePtr twindow = prefx->GetType_2(_bstr_t(L"System.Windows.Window"));

	// 创建Window类型实例
	variant_t objwindow = prefx->CreateInstance(_bstr_t(L"System.Windows.Window"));
	
	// 调用ShowDialog方法
	twindow->InvokeMember_3(_bstr_t(L"ShowDialog"),
		(BindingFlags)(BindingFlags_InvokeMethod|BindingFlags_Instance|BindingFlags_Public),
		NULL, objwindow, NULL);

	/////////////////////////////////////////////////////////////////////////////////////////////////
	// 下面是调用没有强名称的一般程序集的做法

	//_AssemblyPtr assembly = domain->Load_2(_bstr_t(L"ClassLibrary"));

	//_TypePtr t = assembly->GetType_2(_bstr_t(L"ClassLibrary.Class1"));

	//variant_t nullobj;
	//t->InvokeMember_3(_bstr_t(L"WriteVersion"),
	//	(BindingFlags)(BindingFlags_InvokeMethod|BindingFlags_Static|BindingFlags_Public),
	//	NULL, nullobj, NULL);

	///////////////////////////////////////////////////////////////////////////////////////////////////

	// 卸载ICorRuntimeHost(只有它不是智能指针)
	crh->Release();
	crh = NULL;

	// 卸载COM
	CoUninitialize();

	return 0;
}
</mscorlib.tlb></mscoree.h></shlwapi.h></windows.h>
[ 修改于10年5个月前 - 2016/07/07 05:41:04 ]
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的