使用VS2019开发调试Android动态库

这篇具有很好参考价值的文章主要介绍了使用VS2019开发调试Android动态库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 环境准备

1.1 安装JDK:jdk1.8.0_112

1.2 安装Android SDK

SDK可以安装指定的platforms和ndk-bundle。为了兼容性考虑,单独安装了版本比较老的android-ndk-r10b

1.3 安装VS2019

安装VS2019并选择:使用C++的移动开发。

1.4 连接开发手机

使用USB数据线连接开发手机并打开开发手机的USB调试选项。

2. 创建Android动态库工程

2.1 创建新项目

启动VS2019,选择创建新项目

使用VS2019开发调试Android动态库

2.2 选择项目类型

下拉框选择C++、Android,列表选择动态共享库(Android),单击下一

使用VS2019开发调试Android动态库

2.3 填写项目属性

填写项目名称:MyTestSo,选择创建位置,单击创

使用VS2019开发调试Android动态库

2.4 项目创建完成

使用VS2019开发调试Android动态库

3. 创建动态库测试项目

3.1 新建Android项目

在解决方案上单击鼠标右键,选择弹出菜单中的添加->新建项目菜单项。

使用VS2019开发调试Android动态库

3.2 选择项目类型

下拉框选择C++、Android,列表选择Native-Activity应用程序(Android),单击下一步

使用VS2019开发调试Android动态库

3.3 填写项目属性

填写项目名称:Test,单击创建

使用VS2019开发调试Android动态库

 

3.4 项目创建完成

使用VS2019开发调试Android动态库

 3.5 ​​​​​​​添加引用

在左侧Test.NativeActivity项目下的引用上单击鼠标右键,选择弹出菜单:添加引用(R)…

使用VS2019开发调试Android动态库

选中MyTestSo,单击确定完成设置。

  1. 使用VS2019开发调试Android动态库
  2. 4. 设置IDE属性

 选择VS2019菜单项:工具 -> 选项,打开选项设置页面。

选择跨平台 –> C++ -> Android,填写右边的开发工具目录。

  1. 使用VS2019开发调试Android动态库
  2. 5. 设置项目属性

 直接编译创建出来的项目会出现一些如下所示的错误:

使用VS2019开发调试Android动态库

需要设置MyTestSo项目和Test.NativeActivity两个项目的编译属性,以下以MyTestSo项目为例。

打开MytestSo项目属性,选择左侧常规,修改右边的平台工具集为:GCC 4.9,目标API级别为android-L。

使用VS2019开发调试Android动态库

  1. 6. 编译运行

    6.1 修改动态库项目代码

在MyTestSo.cpp源码文件中增加测试函数test,代码如下:

   

void test()
{
	LOGI("Hello World From MyTestSo");
}

使用VS2019开发调试Android动态库

6.2 ​​​​​​​修改测试项目代码

在main.cpp源码文件中调用测试函数test,代码如下:

extern "C" void test();

test();

使用VS2019开发调试Android动态库

 ​​​​​​​6.3 编译运行项目

设置Test.Packaging项目为启动项目,选择编译并运行Test.Packaging项目,查看Logcat输出日志。

项目在有些低版本Android平台上运行可能会崩溃,解决方案参考第7节。

使用VS2019开发调试Android动态库

6.4 调试代码

在main.cpp或者MyTestSo.cpp中设置好断点,调试启动Test.Packaging项目,将会在设置的断点处中断,效果如下图所示:

使用VS2019开发调试Android动态库

7. 崩溃问题解决

项目在有些低版本Android平台上运行可能会崩溃,出现如下错误:

使用VS2019开发调试Android动态库

原因在于libTest.so库依赖了libMyTestSo.so库,项目在运行时加载libTest.so库之前并没有加载libMyTestSo.so库,从而导致了崩溃。解决方案为自定义项目启动类,在启动类里加载so库。

​​​​​​​7.1 自定义项目启动类

在项目Test.Packaging中添加目录结构:src/com/mytest,在mytest目录下创建java源文件MyTestActivity.java,内容如下:

package com.mytest;

import android.app.NativeActivity;

public class MyTestActivity extends NativeActivity
{
    static
    {
	    System.loadLibrary("MyTestSo"); 
        System.loadLibrary("Test"); 
	}
}

使用VS2019开发调试Android动态库 

7.2 修改AndroidManifest.xml

打开AndroidManifest.xml编辑内容,

  • android:hasCode 属性修改为:true
  • android:name 属性修改为:com.mytest.MyTestActivity

使用VS2019开发调试Android动态库

7.3 重新编译运行项目

附录:使用jar包

原文链接:https://retroscience.net/visual-studio-android-ndk-jar-files.html

Android NDK, JAR files, JNI, and Visual Studio

For those of you who don’t know, I have been a Visual Studio user for a long time now, amoung other forms of IDEs I’ve used Visual Studio the most. Something else I also love to use is the C programming language (I wish VS was more up to date for C but it’s good enough). One of the things you can do is develop for Android using NDK and Visual Studio which works fairly well, even though it is using Ant instead of Gradle, I find that it has suited all of my needs so far. That being said, I’m going to drop some tips here on how to make the development process a bit more friendly to be able to interact via JNI and native code.

Note: I am assuming you’ve setup Visual Studio and installed native android development

Update Ant

If you’ve installed Android native development through Visual Studio, you should have everything you need (NDK & SDK) inside of the C:/Microsoft folder. Something we need to do is tell the Ant build system to use a more modern version of JDK (OpenJDK) for building java code. To do this, open the C:/Microsoft/AndroidSDK/25/tools/ant/build.xml file in a text editor and locate the line that starts with <property name="java.target". Change the value of this to 1.7. Do the same thing for <property name="java.source". At this point you should see something like the following:

<!-- compilation options -->
<property name="java.encoding" value="UTF-8" />
<property name="java.target" value="1.7" />
<property name="java.source" value="1.7" />
<property name="java.compilerargs" value="" />
<property name="java.compiler.classpath" value="" />

project.properties

My project properties file in the .sln looks like the following:

# Project target
target=$(androidapilevel)
# Provide path to the directory where prebuilt external jar files are by setting jar.libs.dir=
jar.libs.dir=libs

AndroidManifest.xlm

Since we are going to be writing .jar files and possibly loading in external libraries at runtime, we will need to setup our project to have our own custom native activity code. Inside the AndroidManifest.xlm file you will need to find the android:hasCode="" value in the <application> tag and set it’s value to true. It should look similar to the following:

<application android:label="@string/app_name" android:hasCode="true">
	<!-- ... -->
</application>

Next we will want to set the <activity android:name="" value to our package and activity name that we will be creating. So if your activity class name is going to be FancyActivity then you should have something similar to the following:

<activity android:name="com.PackageName.FancyActivity" android:label="@string/app_name">
	<!-- ... -->
</activity>

Creating our custom activity

Since our full class path will be com.PackageName.FancyActivity we will need to create a few folders inside of our *.Packaging project in Visual studio. Create a folder path named src/com/PackageName/. Next create a file inside of the PackageName folder named FancyActivity.java. Below is the code you should have inside of FancyActivity.java:

package com.PackageName;
import android.app.NativeActivity;
public class FancyActivity extends NativeActivity
{
	static
	{
		//System.loadLibrary("other_lib");
	}
}

Notice the commented out line System.loadLibrary. You can call this as many times as needed, but all you need to do is replace "other_lib" with the name of your library, like System.loadLibrary("fmod"); or something similar. At this point you should be able to build without any issues.

Pro tip: You should always add System.loadLibrary("ProjectName"); where ProjectName is the name of the .so file that is generated for your NDK project build. This will allow you to call native functions from within your Java code (great for callbacks and the like).

Custom JAR files

Now that we’ve setup our activity to better interact with JNI and load other libraries, we are going to look at how to add our own .jar files and access the types within them from native code.

Building .jar files

Make sure and compile your code with -source 1.7 -target 1.7 so that it is matching Ant’s versions we setup earlier. After you’ve built your .class files, ensure your folder structure is correct as it relates to the package path. If your package path for your class(es) is package com.PackageName; then you should have the .class file within a folder structure com/PackageName/*.class. When you build your .jar file it should be for the whole folder structure.

Including .jar files in project

Now that you have your .jar file, you should create a folder named libs in your *.Packaging project. Place your .jar file into this folder and make sure to right click it and select Include In Project.

Accessing your code inside the .jar file

Lets assume for this part you’ve created a class named Dummy with a function that has the signature void SayHi(string name) which will print out “Hello, %s!” (%s = name input string of function). We will use JNI to access your code and invoke your method. Below is the code we will use to call our function. You can place it directly inside of your void android_main(struct android_app* state) function:

JNIEnv* env = NULL;
const ANativeActivity* activity = state->activity;
(*activity->vm)->AttachCurrentThread(activity->vm, &env, 0);

jobject jobj = activity->clazz;
jclass clazz = (*env)->GetObjectClass(env, jobj);
jmethodID getClassLoader = (*env)->GetMethodID(env, clazz, "getClassLoader", "()Ljava/lang/ClassLoader;");
jobject cls = (*env)->CallObjectMethod(env, jobj, getClassLoader);
jclass classLoader = (*env)->FindClass(env, "java/lang/ClassLoader");
jmethodID findClass = (*env)->GetMethodID(env, classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
jstring strClassName = (*env)->NewStringUTF(env, "com.PackageName.Dummy");
jclass fancyActivityClass = (jclass)((*env)->CallObjectMethod(env, cls, findClass, strClassName));
(*env)->DeleteLocalRef(env, strClassName);
jmethodID sayHi = (*env)->GetStaticMethodID(env, fancyActivityClass, "SayHi", "(Ljava/lang/String;)V");
jstring words = (*env)->NewStringUTF(env, "Brent");
(*env)->CallStaticVoidMethod(env, fancyActivityClass, sayHi, words);
(*env)->DeleteLocalRef(env, words);

​​​​​​​Now those who have had a little exposure with JNI might say “Can’t we just use the (*env)->FindClass method? While this may be true for normal Android built in classes, it is not true for our own custom class. The reasoning is that JNI can only look through what is currently on the stack, and believe it or not, even though our FancyActivity is running our code, it isn’t on the stack so we can’t even find it. So what we need to do is get the current activity, then find a method on it called getClassLoader. Once we have this function, we are free to load any class from anywhere that is loaded, even inside our .jar code.

Hope this helps people who are having trouble. It tooke me a full day to figure out all of this stuff because there isn’t anything straight forward on the internet, I had to dig really deep to find all the pieces to put this together!文章来源地址https://www.toymoban.com/news/detail-401538.html

到了这里,关于使用VS2019开发调试Android动态库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • VS2019配置redis客户端的c++开发环境

        目录 需要的开源库: 具体步骤: 遇到的问题: 1. 确保每个项目使用的配置解决方案管理器一样    2.CMAKE 的安装 3. 使用 CMAKE 的路径配置 4. redis 编译报错:jemalloc/jemalloc.h没有这个文件,或者找不到.dll 5. linux 下查看 C++ 版本 6. redis++_static 头文件路径配置    7. d

    2024年02月03日
    浏览(46)
  • VS2019搭建QT6.4开发环境【多图警告^-^】

    安装很简单,这里就不再赘述。 附上VS下载地址:Visual Studio 全家桶 这里就不绕弯子,先说明从5.15版本开始,qt需要下载在线下载器安装。 ** QT下载地址** ; 推荐使用网易邮箱或者QQ邮箱注册,因为会有回执确认操作。 勾选第二条,不要发送信息: 重点选择两个MSVC和MinGW:

    2024年02月04日
    浏览(53)
  • UG/NX二次开发环境配置方法(nx1980+vs2019)

    最近需要尝试nx二次开发,结合网上的文字教程以及一些视频教程,总算是完成了环境的配置以及简单实例的运行——根据用户输入的数据,在原点处创建一个指定长宽高的立方体,配合了简单的UI界面,完成了基本功能。 看到网上关于此类入门的教程并不算多,而且vs和nx版

    2024年02月09日
    浏览(102)
  • cuda调试(一)vs2019-windows-Nsight system--nvtx使用,添加nvToolsExt.h文件

    由于在编程过程中发现不同的网格块的结构,对最后的代码结果有影响,所以想记录一下解决办法。 cuda context (上下文) context类似于CPU进程上下,表示由管理层 Drive 层分配的 资源的生命周期 ,多线程分配调用的GPU资源同属一个context下,通常与CPU的一个进程对应。 CUDA Strea

    2024年02月03日
    浏览(34)
  • VS 远程开发调试环境搭建 简明教程

    在windows上应用程序的开发过程中,总会遇到这样的使用场景,需要在开发机上远程到应用程序的宿主机(常常是以产品形式外发的机台),这时候需要快速搭建简易的远程开发环境。以下几个步骤可以快速帮到你: 1.1 拷贝VS远程调试工具到宿主机 for example: 开发机环境 vs

    2024年02月15日
    浏览(41)
  • Windows环境下C++ 安装OpenSSL库 源码编译及使用(VS2019)

    参考文章 https://blog.csdn.net/xray2/article/details/120497146 之所以多此一举自己写多一篇文章,主要是因为原文内容还是不够详细。而且我安装的时候碰到额外的问题。 一般情况下,引入别人的库,要么把代码直接搞进去,一起编译。要么引入库和头文件(就像MYSQL那样),都不复杂

    2024年02月14日
    浏览(36)
  • VS2019如何调试C语言程序(监视操作)

            在我们编写代码的时候我们经常是遇到与答案不符啊,数组越界啊等问题,有的时候我们的错误在一些不显眼的地方,我们发现不了,但是我们可以确定是那一部分出现了错误,这个时候我就需要去调试。         小白曾经就有一段时间很煎熬,并不知道调试

    2023年04月09日
    浏览(30)
  • VS2019 MFC Teechart V5.1曲线控件使用方法Teechart Activex V5.1控件绘图控件 动态绘图

    Teechart控件安装注册:          1. 将TeeChart5.ocx 复制到C:WindowsSysWOW64。         2. 找到同目录下的cmd.exe。         3. 右键 管理员身份 打开 ,此刻进入的是system32 (不是管理员打开cmd的话,用win + R的话,会提示模块已加载,但对DllRegisterServer的调用失败)。    

    2024年02月05日
    浏览(56)
  • 解决 VS2019 调试 QT 工程时,无法查看 QT 变量的值

    本地环境: windows10 / CMake 生成的 VS2019 工程,使用 Qt5.15.2 产生问题: 调试时,QString 不提示真实内容 解决方法: 1. 在 VS 扩展菜单, 管理扩展    安装 Qt Vs Tools 工具 2. 查找 qt5.natvis.xml 文件 ( Everything 找一下, 我本地找到好几个) C:Users*****AppDataLocalMicrosoftVisualStudio16.0_e1fd65e3Exte

    2024年02月05日
    浏览(61)
  • VS2019静态库与动态库入门操作指南

    源代码的二进制文件; 分为动态编译与静态编译; 1)区别 (1)动态编译不便于发布,静态编译便于发布; (2)动态编译生成的可执行文件体积较小,静态生成的可执行文件体积较大。 ​ Windows中静态库后缀为.lib 动态库后缀为.dll ​ Linux中静态库后缀为.a 动态库后缀为.

    2024年02月06日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包