移动开发多平台代码共享“.NET研究”

简介:   做移动开发快一年了,有幸接触了WM、Symbian、Android、iPhone等多个平台的开发。往往一个软件需要实现多个平台的版本,对于不同平台进行重新编码是一件很费劲的事情,其实我们可以通过代码共用技术,实现对一些代码的重用。

  做移动开发快一年了,有幸接触了WM、Symbian、Android、iPhone等多个平台的开发。往往一个软件需要实现多个平台的版本,对于不同平台进行重新编码是一件很费劲的事情,其实我们可以通过代码共用技术,实现对一些代码的重用。

  这一技术的应用,可用带来不少的好处:

  1. 代码重用:节约开发和维护的时间

  2. 核心代码的保护:将核心代码编译成库,只将库而不是源代码提供给上层开发人员使用。

  3. 。。。。。。

  本文将实现一个支持这几个平台的天气信息查询软件,软件采用C语言去实现调用WebService接口获取天气信息的功能,并将其编译成各种平台能够调用的库,而UI则采用各个平台各自的语言去实现,最终实现底层代码的共用。

先来看看最终的效果图:

  一、底层代码的实现

  我们要调用到WebService接口,需要使用网络

  而对于不同的平台socket的使用上有细微差异,我通过条件编译的方式,实现对不同平台的兼容。

  下面是实现代码:

 
 
// 对于VC的DLL,需要导出函数,而其他的则不需要
头文件Common.h
#ifdef _MSC_VER
#define DLLFLAG _declspec(dllexport)
#
else
#define DLLFLAG
""
#endif
// 通过WebService接口获取天气信息
DLLFLAG char * getWeather( const char * cityName);
源文件Common.c
#include
< string.h >
#include
< Common.h >
#include
< stdlib.h >
// 根据系统加载不同的网络库
#ifdef _MSC_VER
#include
< winsock2.h >
#pragma comment(lib,
" winsock.lib " )
#
else
#include
< sys / socket.h >
#include
< netinet / in.h >
#include
< arpa / inet.h >
#include
< netdb.h >
#endif
#define BUFSIZ
4096
DLLFLAG
char * getWeather( const char * pCityName)
{
// 对于VC需要初始化socket版本
#ifdef _MSC_VER
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD( 2 , 2 ), & wsaData );
#endif
int sockfd = 0 ;
struct sockaddr_in addr;
char text[BUFSIZ] = "" ;
char header[BUFSIZ] = "" ;
char * content = ( char * )malloc(BUFSIZ);
sockfd
= socket(AF_INET, SOCK_STREAM, 0 );
addr.sin_family
= AF_INET;
// 不同平台填充地址字段的方式不同
#ifdef _MSC_VER
addr.sin_addr.S_un.S_addr
= inet_addr( " 222.73.218.218 " );
#
else
inet_aton(
" 222.73.218.218 " , & addr.sin_addr);
#endif
addr.sin_port
= htons( 80 );
memset(header,
0 , sizeof(header));
strcat(header,
" GET /Service.asmx/getWeatherbyCityName?theCityName= " );
strcat(header, pCityName);
strcat(header,
" &theDayFlag=Today HTTP/1.1rn " );
strcat(header,
" Host: www.ayandy.comrnrn " );
connect(sockfd,(struct sockaddr
* ) & addr,sizeof(struct sockaddr_in));
send(sockfd, header, strlen(header),
0 );
memset(text,
0 , BUFSIZ);
memset(content,
0 , BUFSIZ);
recv(sockfd, text, BUFSIZ,
0 );
strcat(content, text);
// while ( recv(sockfd, text, BUFSIZ, 0) > 0)
// {
// strcat(content, text);
// memset(text, 0, BUFSIZ);
// }
// 不同平台关闭socket的方法不同
#ifdef _MSC_VER
closesocket(sockfd);
WSACleanup();
#
else
shutdown(sockfd, SHUT_RDWR);
#endif
return content;
}

  二、Windows Mobile 平台

  对于WM平台,为了与底层库相区别,我们就不用VC去实现UI,而使用C#来实现UI。

  1. 编译dll

  Visual C++  – 智能设备 – 由于没有好的dll模板,我们就建一个“MFC智能设备DLL”,

  取名ShareLib,然后在生成的项目中删除掉没用的文件(比如预编译啥的),添加我们的底层代码文件Common.h和 Common.c,最终文件结构如图:

  然后编译,最终会生成ShareLib.dll文件。

  2. 实现主界面

  新建一个C#的智能设备项目,取名ShareLibTest。

  在Form1.cs文件中,添加对于dll的引用:

 
 
[DllImport( @" ShareLib.dll " ,CharSet = CharSet.Unicode) ]
public static extern IntPtr getWeather( string cityName);

  然后进行界面的设计,最终界面如图:

  然后给按钮设置点击事件:

 
 
try
{
byte [] paraByte = Encoding.UTF8.GetBytes(txtLocation.Text);
IntPtr p
= getWeather(Encoding.Unicode.GetString(paraByte, 0 , paraByte.Length));
string newWeather = Marshal.PtrToStringUni(p);
byte [] strByte = Encoding.Unicode.GetBytes(newWeather);
newWeather
= Encoding.UTF8.GetString(strByte, 0 , strByt上海闵行企业网站设计与制作e.Length);
int a = newWeather.IndexOf( " /> " );
int b = newWeather.IndexOf( " http:// " );
int aLength = " /> " .Length;
newWeather
= newWeather.Substring(a + aLength, b - a - aLength);
newWeather
= newWeather.Replace( "" , "" ).Replace( "" , "" );
txtWeatherInfo.Text
= newWeather;
}
catch (System.Exception )
{
}

  代码中关键的一句就是使用Marshal完成从c的char* 转换为C#的string,还有,需要注意字符的编码,否则可能会导致获取的数据乱码。

  最终,运行程序就能看到效果了。

  三、Android平台

  1. 编上海企业网站制作译so

  对于Android平台,我们用Java实现UI。

  在java中,要调用C/C++,需要使用jni技术。

  我们先写一个java类JniTest.java。

  代码如下:

 
 
public class JniTest {
public native String getWeather(String cityNmae);
}

  然后打开命令提示符:

 
 
// 输入:
javac JniTest.java
// 然后输入:
javah - jni com.luzj.ShareLibTest.JniTest

  最终就会产生com_luzj_ShareLibTest_JniTest.h上海徐汇企业网站制作 文件,复制一份,将后者改为.c。

  打开com_luzj_ShareLibTest_JniTest.c文件,通过#include ”Common.h” 引入底层代码。

  然后去实现那个getWeather函数,在这个函数中主要完成对java的String和C的char*的相互转换工作,代码如下:

 
 
const char * name = (上海企业网站设计与制作span>*env)->GetStringUTFChars(env, cityName, 0);
const char *cWeatherInfo = getWeather( name );
jstring weatherInfo
= (*env)->NewStringUTF(env, cWeatherInfo);
(
*上海闵行企业网站制作="color: #000000;">env)->ReleaseStringUTFChars(env,cityName,name);
return weatherInfo;

  然后编写一个make文件Android.mk,代码如下:

 
 
LOCAL_PATH: = http: // www.cnblogs.com/lib
include $(CLEAR_VARS)
LOCAL_MODULE :
= JniTest
LOCAL_SRC_FILES :
= com_luzj_ShareLibTest_JniTest.c Common.c
include $(BUILD_SHARED_LIBRARY)

  最后,使用NDK-build一下,就会生成Android可用的动态链接库.so文件了。

  2. 实现主界面

  没啥好说的,对于开发过Android的人都能做到。

  然后在Activity中通过代码加载动态链接库:

 
 
// 加载c库
static {
System.loadLibrary(
" JniTest " );
}

  最后在要获取天气数据的地方调用JniTest类的中的getWeather方法即可。

  四、iPhone平台

  在iPhone平台,对于UI,使用Obj-C来实现。

  在iPhone平台上,我们可以将公用代码编译成静态库然后给程序调用。

  1. 编译静态库

  首先,通过“Cocoa Touch Static Library”创建一个静态库的工程:

  将我们的底层库添加上去,编译一下,就会生成一个以“.a”为后缀的静态库了。

  2. 实现主界面

  拉个按钮到界面上去,给它添加事件。

  主要代码就下面两行,完成了NSString 与 char* 的相互转化,并调用了接口:

 
 
char * strWeatherInfo = getWeather([txtLocation.text UTF8String]);
NSString
* weatherInfo = [NSString stringWithUTF8String:strWeatherInfo];

  最后将数据显示到界面上即可。

  五、Symbian平台

  我始终对这个平台没啥好感,况且这个平台的开发本身就是使用C、C++,实现代码共用很容易的,在此我就不浪费笔墨了,有兴趣的自己试试。

  六、总结

  这一技术还是很有使用前景的,比如游戏开发者,可用通过代码共用,用Open GL 实现一个底层的游戏引擎给各个平台使用。

  由于时间的关系,代码中对于异常的处理和一些条件的判断都没有去做,有兴趣的同学自己完善!

  文章中的Demo已经打包,需要的可以自行下载。

  下载地址:http://u.115.com/file/dn69hko2

  在我的独立博客还有一些好文章,有兴趣的可以去看看:http://luzj.me/share-lib-test-mobil.html

目录
相关文章
|
20天前
|
IDE 开发工具 Android开发
移动应用开发之旅:探索Android和iOS平台
在这篇文章中,我们将深入探讨移动应用开发的两个主要平台——Android和iOS。我们将了解它们的操作系统、开发环境和工具,并通过代码示例展示如何在这两个平台上创建一个简单的“Hello World”应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧,帮助你更好地理解和掌握移动应用开发。
44 17
|
24天前
|
开发框架 .NET PHP
ASP.NET Web Pages - 添加 Razor 代码
ASP.NET Web Pages 使用 Razor 标记添加服务器端代码,支持 C# 和 Visual Basic。Razor 语法简洁易学,类似于 ASP 和 PHP。例如,在网页中加入 `@DateTime.Now` 可以实时显示当前时间。
|
1月前
|
机器学习/深度学习 人工智能 Cloud Native
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台。本文深入解析 .NET 的核心优势,探讨其在企业级应用、Web 开发及移动应用等领域的应用案例,并展望未来在人工智能、云原生等方面的发展趋势。
39 3
|
1月前
|
敏捷开发 缓存 中间件
.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素
本文深入探讨了.NET技术的高效开发模式,涵盖面向对象编程、良好架构设计及高效代码编写与管理三大关键要素,并通过企业级应用和Web应用开发的实践案例,展示了如何在实际项目中应用这些模式,旨在为开发者提供有益的参考和指导。
25 3
|
1月前
|
存储 设计模式 编解码
.NET 8.0 通用管理平台,支持模块化、WinForms 和 WPF
【11月更文挑战第5天】本文分析了.NET 8.0 通用管理平台在模块化、WinForms 和 WPF 方面的优势。模块化设计提升了系统的可维护性和可扩展性,提高了代码复用性;WinForms 提供了丰富的控件库和简单易用的开发模式,技术成熟稳定;WPF 支持强大的数据绑定和 MVVM 模式,具备丰富的图形和动画功能,以及灵活的布局系统。
|
2月前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
33 1
|
2月前
|
前端开发 JavaScript C#
CodeMaid:一款基于.NET开发的Visual Studio代码简化和整理实用插件
CodeMaid:一款基于.NET开发的Visual Studio代码简化和整理实用插件
|
4月前
|
Kubernetes 监控 Devops
【独家揭秘】.NET项目中的DevOps实践:从代码提交到生产部署,你不知道的那些事!
【8月更文挑战第28天】.NET 项目中的 DevOps 实践贯穿代码提交到生产部署全流程,涵盖健壮的源代码管理、GitFlow 工作流、持续集成与部署、容器化及监控日志记录。通过 Git、CI/CD 工具、Kubernetes 及日志框架的最佳实践应用,显著提升软件开发效率与质量。本文通过具体示例,助力开发者构建高效可靠的 DevOps 流程,确保项目成功交付。
95 0
|
4月前
|
XML 开发框架 .NET
.NET框架:软件开发领域的瑞士军刀,如何让初学者变身代码艺术家——从基础架构到独特优势,一篇不可错过的深度解读。
【8月更文挑战第28天】.NET框架是由微软推出的统一开发平台,支持多种编程语言,简化应用程序的开发与部署。其核心组件包括公共语言运行库(CLR)和类库(FCL)。CLR负责内存管理、线程管理和异常处理等任务,确保代码稳定运行;FCL则提供了丰富的类和接口,涵盖网络、数据访问、安全性等多个领域,提高开发效率。此外,.NET框架还支持跨语言互操作,允许开发者使用C#、VB.NET等语言编写代码并无缝集成。这一框架凭借其强大的功能和广泛的社区支持,已成为软件开发领域的重要工具,适合初学者深入学习以奠定职业生涯基础。
117 1
|
3月前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
87 0