[源码下载]

不可或缺 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. C++ const && define

    本文记录了C++中的const关键字的内容,分为3个部分,const和define的区别,const的作用,const的使用. const和define的区别 const的作用 const用于定义常量 ...

  2. vs2013中的“任务列表”菜单

    以前在java项目中经常用到todo. 现在vs2013也完美支持了. 首先,对于目前不确定而尚需完善的代码,在前面加 //TODO:by who --注释文字,比如: //TODO:lhl--类目I ...

  3. Atitit. Atiposter 发帖机 新特性 poster new feature v11  .docx

    Atitit. Atiposter 发帖机 新特性 poster new feature v11  .docx 1.1.  版本历史1 2. 1. 未来版本规划2 2.1. V12版本规划2 2.2. ...

  4. mysql如果数据不存在,则插入新数据,否则更新的实现方法

    mysql如果数据不存在,则插入新数据,否则更新的实现方法 //如果不存在,则插入新数据 $sql = "INSERT INTO {$ecs->table('cat_lang')} ( ...

  5. KnockoutJS 3.X API 第四章 表单绑定(12) selectedOptions、uniqueName绑定

    selectedOptions绑定目的 selectedOptions绑定控制当前选择多选列表中的哪些元素. 这旨在与<select>元素和选项绑定结合使用. 当用户选择或取消选择多选列表 ...

  6. 那些年我们写过的T-SQL(下篇)

    下篇的内容很多都会在工作中用到,尤其是可编程对象,那些年我们写过的存储过程,有木有?到目前为止很多大型传统企业仍然很依赖存储过程.这部分主要难理解的部分是事务和锁机制这块,本文会进行简单的阐述.虽然很 ...

  7. Symfony2模版引擎使用说明手册

    一.基本使用 {{ demo }}输出一个demo变量; {% func %}通常是包含一个twig函数例如 for; 举个for循环的例子: {% for i in 0..10 %} <em& ...

  8. ASP.NET MVC图片管理(上传,预览与显示)

    先看看效果(下面gif动画制作有点大,5.71MB): 题外话:上面选择图片来源于Insus.NET的新浪微博:http://weibo.com/104325017 也是昨晚(2015-07-03)I ...

  9. php分享(三十六)mysql中关联表更新

    一:关联不同的表更新 1: 通过where关联更新 update student s, city c set s.province_name = c.province_name, s.city_nam ...

  10. 邻接表有向图(三)之 Java详解

    前面分别介绍了邻接表有向图的C和C++实现,本文通过Java实现邻接表有向图. 目录 1. 邻接表有向图的介绍 2. 邻接表有向图的代码说明 3. 邻接表有向图的完整源码 转载请注明出处:http:/ ...