wp8开发中c++与c#的交互

 

c++与c#的交互

项目基本上是c++写的,现在要移植到wp8上,坑啊,c#不会啊

 

查了下资料,发现目前来说,c++与c#交互主要有2中方法:

 

http://stackoverflow.com/questions/14434874/calling-c-sharp-method-from-c-code-in-wp8

http://www.cnblogs.com/zhxilin/archive/2013/03/20/2971331.html

 

这2中方法都不太熟,但是看着第一种方法简单,所以采取了第一种方法,具体过程如下:

 

1. 在项目的解决方案下,添加一个新项目,选择 windows phone空动态链接库,我这里输入的工程名为Dll

注意,如果添加windows phone运行时组件也是可以的,二者的区别在于动态链接库字符集默认为ascii

而运行时组件字符集默认为Unicode,这个是个人实验得出的,具体到个人,可能会有不同

如果选择动态链接库,需要做如下设置:

 

选择,项目->属性

在 c/c++, 常规,使用Windows运行时扩展 选项,选择 是(/ZW);

 

在 c/c++, 预处理器,预处理器定义 中添加 _WINRT_DLL,这样如果不做,可能会在运行时

遇见Error in the DLL (Exception from HRESULT: 0x800401F9 (CO_E_ERRORINDLL))

的错误

 

在 c/c++, 代码生成,启动最小重新生成 选项,选择 否(/Gm-), 这里默认为是,

如果设置了使用Windows运行时扩展,而这里不调整,会提示/ZW 与 /Gm- 不兼容

 

在 连接器,Windows元数据,生成Windows元数据 选项,选择 是(/WINMD), 这里选择生成元数据供

C#调用c++;

 

2. 在头文件Dll.h中添加代码,如下:

#pragma once

namespace Dll
{
	public interface class ICallback
	{
	public:
		virtual void Exec(Platform::String ^Command, Platform::String ^Param);
	};

	public ref class MYTest sealed
	{
	public:
		MYTest();
		void Init();
		int AT(int a, int b);
		void SetCallback(ICallback ^Callback);
		void SetRet(int result);
		void show();
	};
}

 

其实这里主要的就是那个interface的类了,ICallback里面的虚函数Exec在C#里面实现,供c++调用

下面的那个MYTest类里面的函数,最主要的是SetCallback,用来获取c#里面的对象

 

在Dll.cpp中添加方法,代码如下:

#include "pch.h"
#include "TDll.h"
#include <stdio.h>
#include <string.h>

using namespace Dll;

ICallback ^CSCallback = nullptr;

void * handle = nullptr;
int ret;

MYTest::MYTest()
{
	ret = -1;
}

void MYTest::Init()
{
	
}

int MYTest::AT(int a, int b)
{
	if (CSCallback != nullptr)
		CSCallback->Exec("Hello", "World!");
	
	return a + b;
}

void MYTest::SetCallback(ICallback ^Callback)
{
	CSCallback = Callback;
}

void MYTest::SetRet(int result)
{
	ret = result;
}

void MYTest::show()
{
	char ch[10] = { 0 };
	sprintf(ch, "ret:%d\n", ret);
	OutputDebugString(ch);
}

 

其中AT方法是一个调用c#方法的函数,明显得,调用Exec方法,传递2个参数

 

3. 在wp8工程 中添加如下代码:

 

//MainPage.xaml.cs:

namespace QRCode
{
	private MYTest test = new MYTest();
	
	......
	
	private void Button_Click(object sender, RoutedEventArgs e)
	{
		count++;
		if (count == 1)
		{
			int ret = test.AT(2, 3);
			Debug.WriteLine("main page:" + ret);
		}
		else
			test.show();
	}
	
	......
	
	public class CallbackImpl : ICallback
    {
        public void Exec(String Command, String Param)
        {
            Debug.WriteLine(Command + Param);
            (Application.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri("/ScanPage.xaml", UriKind.Relative));            
        }
    }
}

 

CallbackImpl里面的Exec是c++中相应虚函数的实现,这里Exec主要是用来跳转到ScanPage.xaml页面

//ScanPage.xaml.cs:

namespace QRCode
{
	private MYTest te = new MYTest();
	
	.....
	
	private void ScanPreviewBuffer()
	{
		.....
		te.SetRet(0);
        te.show();
		.....
	}
}

 

ScanPage扫描二维码,如果成功,设置c++中的ret作为返回值,返回

 

注意,如果Dll依赖与其他dll,需要将依赖的dll手动添加到wp8工程当中,

否则,wp8打包时是不会主动将依赖dll打包进xap包的,但编译不会报错,运行时会报错

 

4. 选择wp8工程,右键,添加,引用,浏览,找到Dll.wind,确定

编译,第一次编译可能会提示wp8工程错误,再次编译就好了,主要是第一次编译找不到.wind

 

 

有时候会遇见Access is denied的运行错误,此时,打开wp8工程下Porperties标签,

打开WMAppManifest.xml文件,选择 功能 项,勾选需要的功能

比如这里用到摄像头,所以要勾选ID_CAP_ISV_CAMERA项

 

 

其实不麻烦,主要是个人水平问题,感觉就一个字,坑

 

具体的代码可以在下面的链接中下载

QRcode

 

 

参考:

http://stackoverflow.com/questions/14434874/calling-c-sharp-method-from-c-code-in-wp8

http://blog.webrox.fr/?p=67

http://www.cnblogs.com/zhxilin/archive/2013/03/20/2971331.html

http://hi.baidu.com/huangjianspace/item/e437fb1ee194caf29d778a03

https://social.msdn.microsoft.com/Forums/windowsapps/en-US/3db59292-

8abb-4bfd-a46e-926ad78239f9/wp81-getfoldersasync-access-is-denied-ex

ception-from-hresult-0x80070005-eaccessdenied?forum=wpdevelop

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值