[源码下载]

不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native

作者:webabcd

介绍
不可或缺 Windows Native 之 C++

  • windows app native
  • android app native
  • ios app native

示例
一、演示 windows app native 开发
1、native 层
CppCx.h

#pragma once 

#include <string>

using namespace std;

namespace NativeDll
{
class CppCx
{
public:
string Hello(string name);
};
}

CppCx.cpp

/*
* 演示 C#, C++/CX, C/C++ 间的通信
*
* 本例是 C/C++ 部分
*/ #include "pch.h"
#include "CppCx.h"
#include "DemoCx.h" using namespace NativeDll; string CppCx::Hello(string name)
{
// C/C++ 通过 C++/CX 调用 C#
if (DemoCx::GlobalCallback != nullptr)
DemoCx::GlobalCallback->Cx2Cs("c/c++ to c++/cx to cs"); return "hello: " + name;
}

2、C++/CX 层
DemoCx.h

#pragma once 

#include "ICallback.h"

using namespace Platform;

namespace NativeDll
{
// ref class 可被输出到元数据(winmd - Windows Metadata),以便其他托管程序调用
public ref class DemoCx sealed
{
public:
// 用“^”标记的,系统会负责他们的引用计数,当引用计数为 0 时,它们会被销毁
String^ HelloCx(String^ name); String^ HelloCpp(String^ name); // 由 C# 调用,用于设置 ICallback 对象
void SetCallback(ICallback^ callback); // 由 C++/CX 调用,用于通过 ICallback 向 C# 发送数据
property static ICallback^ GlobalCallback;
};
}

DemoCx.cpp

/*
* 演示 C#, C++/CX, C/C++ 间的通信
*
* 本例是 C++/CX 部分
*
* 为了支持 Windows Runtime Component 这种方式,所以引入 Microsoft created the Visual C++ component extensions (C++/CX),可以将其看作是连接“调用者”和“C/C++”之间的桥梁,元数据是 windows metadata (.winmd) files
* 为了让“调用者”调用 Windows Runtime Component,所以 C++/CX 会有自己的一些数据类型,比如字符串是 Platform::String^ 类型的,这样才能让“调用者”调用
* 关于 C++/CX 的相关知识请参见:https://msdn.microsoft.com/en-us/library/hh755822.aspx
*/ #include "pch.h"
#include "DemoCx.h"
#include "CppCx.h"
#include "cppHelper.h" using namespace NativeDll; String^ DemoCx::HelloCx(String^ name)
{
// 如果 C# 端设置了 ICallback 对象,则可以在 C++/Cx 端向 C# 端发送数据
if (GlobalCallback != nullptr)
GlobalCallback->Cx2Cs("c++/cx to cs"); return "hello: " + name;
} // 由 C# 调用,用于设置 ICallback 对象
void DemoCx::SetCallback(ICallback^ callback)
{
GlobalCallback = callback;
} String^ DemoCx::HelloCpp(String^ name)
{
// C++/CX 与 C/C++ 通信时,如果要传递字符串,则要对字符串做转换
string cppName = ws2s_3(std::wstring(name->Data())); // C++/CX 调用 C/C++
CppCx cppCx;
string cppResult = cppCx.Hello(cppName);
String^ cxResult = ref new Platform::String(s2ws_3(cppResult).c_str()); return cxResult;
}

3、托管代码层
Cx.xaml

<Page
x:Class="NativeDemo.Demo.Cx"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:NativeDemo.Demo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" TextAlignment="Left" FontSize="24.667" TextWrapping="Wrap" /> </StackPanel>
</Grid>
</Page>

Cx.xaml.cs

/*
* 演示 C#, C++/CX, C/C++ 间的通信
*
* 本例是 C# 部分
*
*
* C# 与 C++/CX 间通信;C++/CX 与 C/C++ 间通信;C# 通过 C++/CX 与 C/C++ 间通信
*/ using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; namespace NativeDemo.Demo
{
public sealed partial class Cx : Page
{
public Cx()
{
this.InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
NativeDll.DemoCx demoCx = new NativeDll.DemoCx(); MyCallback myCallback = new MyCallback();
myCallback.MessageReceived += myCallback_MessageReceived;
demoCx.SetCallback(myCallback); // C# 调用 C++/CX
lblMsg.Text += demoCx.HelloCx("cs to c++/cx");
lblMsg.Text += Environment.NewLine; // C# 通过 C++/CX 调用 C/C++
lblMsg.Text += demoCx.HelloCpp("cs to c++/cx to c/c++");
lblMsg.Text += Environment.NewLine;
} async void myCallback_MessageReceived(object sender, MessageEventArgs e)
{
MyCallback myCallback = (MyCallback)sender; await lblMsg.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
lblMsg.Text += e.Message;
lblMsg.Text += Environment.NewLine;
});
}
} // 实现 C++/CX 中的 ICallback 接口
public class MyCallback : NativeDll.ICallback
{
// 收到 C++/CX 直接发送过来的数据,或者 C/C++ 通过 C++/CX 发送过来的数据
public void Cx2Cs(string message)
{
OnMessageReceived(new MessageEventArgs { Message = message });
} public event EventHandler<MessageEventArgs> MessageReceived;
protected virtual void OnMessageReceived(MessageEventArgs e)
{
EventHandler<MessageEventArgs> handler = MessageReceived;
if (handler != null)
handler(this, e);
}
} public class MessageEventArgs : EventArgs
{
public string Message { get; set; }
} }

二、演示 android app native 开发
1、native 层(C 语言)
cHello.h

#ifndef _MYHEAD_CHELLO_
#define _MYHEAD_CHELLO_
#ifdef __cplusplus
extern "C"
{
#endif char *hello(const char *name); #ifdef __cplusplus
}
#endif
#endif

cHello.c

#include "cHello.h"
#include <stdlib.h> char *str_concat2(const char *, const char *); char *hello(const char *name)
{
return str_concat2("hello: ", name);
} char *str_concat2(const char *str1, const char *str2)
{
char *result;
result = (char *)malloc(strlen(str1) + strlen(str2) + );
if (!result)
{
exit(EXIT_FAILURE);
} strncpy(result, str1, strlen(str1) + );
strncat(result, str2, strlen(str1) + strlen(str2) + );
return result;
}

2、native 层(C++)
CppHello.h

#ifndef _MYHEAD_CPPHELLO_
#define _MYHEAD_CPPHELLO_ #include <string> using namespace std; namespace MyNs
{
class CppHello
{
public:
string Hello(string name);
};
} #endif

CppHello.cpp

#include "CppHello.h"

using namespace MyNs;

string CppHello::Hello(string name)
{
return "hello: " + name;
}

3、jni 层
jniDemo.h

#include <jni.h>

#ifndef _Included_com_cnblogs_webabcd_jniDemo
#define _Included_com_cnblogs_webabcd_jniDemo
#ifdef __cplusplus
extern "C" {
#endif // 注意函数名的命名规则
JNIEXPORT jstring JNICALL Java_com_example_androidnative_MainActivity_helloJniCpp(JNIEnv *env, jobject obj, jstring name); JNIEXPORT jstring JNICALL Java_com_example_androidnative_MainActivity_helloJniC(JNIEnv *env, jobject obj, jstring name); #ifdef __cplusplus
}
#endif
#endif

jniDemo.cpp

/*
* jni(Java Native Interface) - 详细文档参见 http://docs.oracle.com/javase/7/docs/technotes/guides/jni/
* ndk(Native Development Kit) - 下载 ndk 后,其目录内有详细的文档
* cygwin - 在 windows 平台上运行的类 UNIX 模拟环境,可以调用 ndk 编译 so
*
*
* 为了使 jni 能支持 c++ 需要这么做:
* 1、将本文件的后缀名从 .c 修改为 .cpp(c++ 文件的扩展名可以通过 Android.mk 的 LOCAL_CPP_EXTENSION 指定)
* 2、按本例的方式配置 Application.mk 文件(如果只想支持 c 语言的话,则可以不要此文件)
*/ #include "jniDemo.h"
#include "CppHello.h"
#include "cHello.h" void jni2java(JNIEnv *); // 对应 MainActivity 类中的 public native String helloJniCpp(String name); 注意函数的命名规则
JNIEXPORT jstring JNICALL Java_com_example_androidnative_MainActivity_helloJniCpp(JNIEnv *env, jobject obj, jstring name)
{
jni2java(env); MyNs::CppHello cppHello;
const char *charName = env->GetStringUTFChars(name, ); // jstring to char
std::string stringName(charName); // jstring to string
std::string stringResult = cppHello.Hello(stringName);
const char *charResult = stringResult.data(); // string to char
jstring jstringResult = env->NewStringUTF(charResult); // char to jstring
return jstringResult; /*
* 调用 jni 函数时注意(对于 C 和 CPP 来说,JNIEnv 的含义不同,具体请查看文档):
* 1、C 的用法示例:jstring jstringResult = (*env)->NewStringUTF(env, charResult); // char to jstring
* 2、CPP 的用法示例:jstring jstringResult = env->NewStringUTF(charResult); // char to jstring
*/
} // 对应 MainActivity 类中的 public native String helloJniC(String name); 注意函数的命名规则
JNIEXPORT jstring JNICALL Java_com_example_androidnative_MainActivity_helloJniC(JNIEnv *env, jobject obj, jstring name)
{
jni2java(env); const char *charName = env->GetStringUTFChars(name, ); // jstring to char
char *charResult = hello(charName);
jstring jstringResult = env->NewStringUTF(charResult); // char to jstring
free(charResult);
return jstringResult;
} // 调用 MainActivity 类中的 public static void helloJava(String message); 函数
void jni2java(JNIEnv *env)
{
const char *className = "com/example/androidnative/MainActivity"; // 注意类名规则
jclass cla = env->FindClass(className);
// 第三个参数中:(Ljava/lang/String;)代表 java 中的被调用的函数的参数是 String 类型;V 代表 java 中的被调用的函数的返回值是 void 类型
jmethodID method = env->GetStaticMethodID(cla, "helloJava", "(Ljava/lang/String;)V");
jstring result = env->NewStringUTF("jni to java");
env->CallStaticVoidMethod(cla, method, result);
}

编译相关
Application.mk

APP_STL := stlport_static #以静态链接的方式使用stlport版本的STL
APP_CPPFLAGS := -fexceptions -frtti #允许异常功能,及运行时类型识别
APP_CPPFLAGS +=-std=c++ #允许使用c++11的函数等功能
APP_CPPFLAGS +=-fpermissive #此项有效时表示宽松的编译形式,比如没有用到的代码中有错误也可以通过编

Android.mk

LOCAL_PATH := $(call my-dir)

#模块1
include $(CLEAR_VARS) #清除 LOCAL_MODULE, LOCAL_SRC_FILES 之类的变量
LOCAL_CPP_EXTENSION := .cpp # C++ 文件的扩展名
LOCAL_MODULE := jniDemo # 模块名。如果模块名为“abc”,则此模块将会生成“libabc.so”文件。
LOCAL_SRC_FILES := jniDemo.cpp CppHello.cpp cHello.c # 需要编译的源文件
include $(BUILD_SHARED_LIBRARY) # 编译当前模块 #模块2

4、托管代码层
MainActivity.java

/*
* 演示 java 如何通过 jni 与 C/C++ 互相通信
*/ package com.example.androidnative; import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView; public class MainActivity extends Activity { private static TextView txtMsg; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); txtMsg = (TextView) this.findViewById(R.id.txtMsg); // 加载 so
System.loadLibrary("jniDemo"); // java 调用 jni, c
String resultC = helloJniC("java to jni to c");
txtMsg.append(resultC);
txtMsg.append("\n"); // java 调用 jni, c++
String resultCpp = helloJniCpp("java to jni to c++");
txtMsg.append(resultCpp);
txtMsg.append("\n");
} // native function(对应的 jni 函数参见 jniDemo.cpp)
public native String helloJniC(String name);
public native String helloJniCpp(String name); // jni 调用 java
public static void helloJava(String message)
{
txtMsg.append(message);
txtMsg.append("\n");
}
}

三、演示 ios app native 开发(无论是 oc 还是 swift 都是 native 开发,本例演示 oc, c, c++ 混编)
ViewController.h

//
// ViewController.h
// IosNative
//
// Created by wanglei on 4/24/15.
// Copyright (c) 2015 webabcd. All rights reserved.
// #import <UIKit/UIKit.h> @interface ViewController : UIViewController @end

ViewController.mm

/*
* 演示 objective-c 如何与 C/C++ 互相通信
*
* objective-c 是面向对象的 c 语言,本身就是 Native 的,完全兼容 c 语言,可以与 C/C++ 混编
*
* 注:为了支持 C++ 需要把本文件的后缀名由 .m 修改为 .mm
*/ #import "ViewController.h" #include <string> @interface ViewController () @end @implementation ViewController char *hello(const char *);
class CppHello; - (void)viewDidLoad
{
[super viewDidLoad]; [self helloC:@"oc to c"];
[self helloCpp:@"oc to c++"];
} // oc 调用 c
- (void)helloC:(NSString *)name
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
[self.view addSubview:label]; const char *charName = [name UTF8String]; // nsstring to char
char *charResult = hello(charName);
NSString *nsstringResult = [[NSString alloc] initWithCString:charResult encoding:NSUTF8StringEncoding]; // char to nsstring
free(charResult); label.text = nsstringResult;
} // oc 调用 c++
- (void)helloCpp:(NSString *)name
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
[self.view addSubview:label]; string stringName = [name UTF8String]; // nsstring to string
MyNs::CppHello cppHello;
string stringResult = cppHello.Hello(stringName);
NSString *nsstringResult = [[NSString alloc] initWithCString:stringResult.c_str() encoding:NSUTF8StringEncoding]; // string to nsstring label.text = nsstringResult;
} char *hello(const char *name)
{
// c 调用 oc(别忘了 #import <Foundation/Foundation.h>,本例中不用是因为 UIViewController 已经导入这个头文件了)
NSLog(@"c to oc"); char *s = "hello: "; char *result;
result = (char *)malloc(strlen(s) + strlen(name) + );
if (!result)
exit(EXIT_FAILURE); strncpy(result, s, strlen(s) + );
strncat(result, name, strlen(s) + strlen(name) + ); return result;
} using namespace std;
namespace MyNs
{
class CppHello
{
public:
string Hello(string name);
};
}
string MyNs::CppHello::Hello(string name)
{
// c++ 调用 oc(别忘了 #import <Foundation/Foundation.h>,本例中不用是因为 UIViewController 已经导入这个头文件了)
NSLog(@"c++ to oc"); return "hello: " + name;
} @end

OK
[源码下载]

不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native的更多相关文章

  1. App Transfer:苹果允许iOS App从一个开发者帐号转至另一个开发者账号

    App Transfer:苹果允许iOS App从一个开发者帐号转至另一个开发者账号 苹果在WWDC上宣布超过30万的开发者为iOS平台开发超过90万的应用,你可能会想到有人想出售或者购买app. 现 ...

  2. 极速创建 IOS APP !涛舅舅苹果 IOS APP自助生成系统正式上线

    经过大量的测试和开发工作,涛舅舅苹果 IOS APP自助生成系统正式上线! 本系统主要功能: 1.用最最简单的方式将H5网站打包生成一个苹果APP 2.只需要提供APP标题,H5网站首页url地址,一 ...

  3. 极速创建 IOS APP !涛舅舅苹果 IOS APP自助生成系统!不用证书、不用越狱、永久可用

    不用签名将网页封装成苹果APP,无需苹果企业签名,IPA签名,ios签名,免越狱安装 (本方法只支持网站封装app,原生的用不了,详细请咨询客服) 近期很多朋友问我把网站变成app的方法,原因很多种, ...

  4. 为什么我的 app:actionViewClass="android.widget.SearchView"和app:showAsAction="ifRoom|collapseActionView"才有

    http://blog.csdn.net/cdnight/article/details/48029911 <item android:id="@+id/action_search&q ...

  5. Android Studio 提示Error running app: No Android facet found for app

    错误解决办法如下: 可以通过以下几个步骤解决该问题: 1) 点击菜单File -> 选择Project Structure, 或使用快捷键 (Ctrl+Alt+Shift+S) 打开”Proje ...

  6. 用Xamarin和Visual Studio编写iOS App

    一说开发 iOS app,你立马就会想到苹果的开发语言 Objective C/Swift 和 Xcode.但是,这并不是唯一的选择,我们完全可以使用别的语言和框架. 一种主流的替换方案是 Xamar ...

  7. 勾勾街——一个专注于免越狱免签名的苹果ios APP打包生成的网站

    自涛舅舅研发的“苹果ios APP自助生成系统”上线以来,每天都有大量的用户注册和生成免越狱app,为什么? 因为我们有明显的技术优势,APP不需要上架appstore, 生成APP又不需要企业签名证 ...

  8. 勾勾街:一个专业的苹果ios app 自助打包的网站,免越狱,免证书签名

    众所周知,苹果的APP开发是需要基于MAC环境的,而我们很多的开发者并没有这样的条件,如果单单为发布一款app就去买一台价格昂贵的MAC那成本就太高了! 就算你有一台MAC,也有能力自己开发出一款基于 ...

  9. Deploying JRE (Native Plug-in) for Windows Clients in Oracle E-Business Suite Release 12 (文档 ID 393931.1)

    In This Document Section 1: Overview Section 2: Pre-Upgrade Steps Section 3: Upgrade and Configurati ...

随机推荐

  1. osgi dm

    看了http://developer.51cto.com/art/200909/154863.htm 真心感到,最强大最有组织的技术网站还是 51cto,牛人应该也是最多的. 以前逛51cto的比较少 ...

  2. 品味FastDFS~目录

    回到占占推荐博客索引 参考文献:http://baike.baidu.com/view/973383.htm#sub5143372 分布式文件系统(DFS,Distributed File Syste ...

  3. Atitit qzone qq空间博客自动点赞与评论工具的设计与实现

    Atitit qzone qq空间博客自动点赞与评论工具的设计与实现 Qzone发送评论的原理 首先,有个a标签, <a class="c_tx3" href="j ...

  4. c#设计模式-命令模式

    一. 命令(Command)模式 命令(Command)模式属于对象的行为模式[GOF95].命令模式又称为行动(Action)模式或交易(Transaction)模式.命令模式把一个请求或者操作封装 ...

  5. 遍历后台的List,让前台的多选宽被选中

    后端代码: /** * 获取优惠卷分页信息 * * * @param ph * 包括查询条件以及分页查询条件 * */ @Override public DataGrid<AppCmsCoupo ...

  6. APP性能测试

    方法一: 本地安装安卓模拟器,用LR选择模拟器录制方式录制 方法二: 手机真机需要root,可以在电脑上下载一键root工具(如卓大师),然后手机和电脑用数据线连接,然后root. 在手机上运行 Mo ...

  7. POJ3069 POJ2586 解题报告(异曲同工的贪心算法)

    [POJ 3069](2586见下) 原题在此:http://poj.org/problem?id=3069 题目大意: 一个直线上有N个点.点i的距离是Xi.从这些点中选取若干个加上标记.要求:对于 ...

  8. Grunt 安装与配置环境

    当时学习 Grunt 的时候,真是很头疼.分了两个时间段,学习了两次才硬啃下来,之后才能用在项目中.主要原因我认为是学习资料和文档上面写的太高端了.这类的文档或者资料有个显著特点,上来先简单介绍一下这 ...

  9. UML基础系列:用例图

    1. 概述 用例图(Use Case Diagram)描述“用户.需求.系统功能单元”之间的关系,是参与者所能观察和使用到的系统功能模型图. 用例图用于需求分析阶段 用例图包含6个基本元素:参与者(A ...

  10. BOM之location对象

    定义 location提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能.location是一个很特别的对象,因为它既是window对象的属性,也是document对象的属性.换句话说,wi ...