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

猜你喜欢

转载自blog.csdn.net/ybn187/article/details/40827993