Skip to content

Commit

Permalink
dlopen ok
Browse files Browse the repository at this point in the history
  • Loading branch information
baiiu committed Dec 24, 2020
1 parent 70980dd commit 031644c
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 11 deletions.
2 changes: 1 addition & 1 deletion jni/jnitest/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".HomeActivity">
<activity android:name=".SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
9 changes: 9 additions & 0 deletions jni/jnitest/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ add_library(
SHARED
testSocket/SocketTest.cpp
)
add_library(
dlopen-lib
SHARED
dlopen/testdlopen.cpp
)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
Expand Down Expand Up @@ -146,4 +151,8 @@ target_link_libraries(
target_link_libraries(
socket-lib
${log-lib}
)
target_link_libraries(
dlopen-lib
${log-lib}
)
43 changes: 43 additions & 0 deletions jni/jnitest/src/main/cpp/dlopen/testdlopen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Created by baiiu on 2020/12/24.
//
#include <dlfcn.h>
#include <string.h>
#include <cstdlib>
#include "jni.h"
#include "log.h"

extern "C"
JNIEXPORT void JNICALL
Java_com_baiiu_jnitest_dlopen_DLOpenFragment_testdlopen(JNIEnv *env, jobject thiz, jstring jstr) {
const char *soPath = env->GetStringUTFChars(jstr, JNI_FALSE);

LOGD("native--> soPath: %s", soPath);
void *handle = dlopen(soPath, RTLD_NOW);

char *error_msg = nullptr;
if (handle == nullptr) {
error_msg = strdup(dlerror());
LOGD("%s", error_msg);
}

LOGD("handle is %p", handle);

// void *sym = dlsym(handle, "fibonacci");
void *sym = dlsym(handle, "_Z9fibonaccii");
if (sym == nullptr) {
LOGD("can not find the function");
return;
}

using FIBONACCI = int (*)(int);
FIBONACCI fibonacci = reinterpret_cast<FIBONACCI>(sym);
int result = (*fibonacci)(5);

LOGD("fibonacci result is: %d", result);

dlclose(handle);

env->ReleaseStringUTFChars(jstr, soPath);

}
7 changes: 3 additions & 4 deletions jni/jnitest/src/main/cpp/testSocket/SocketTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
#include <log.h>
#include <unistd.h>


int function(int n) {
int fibonacci(int n) {
if (n == 1) return 1;
if (n == 2) return 1;

return function(n - 1) + function(n - 2);
return fibonacci(n - 1) + fibonacci(n - 2);
}


Expand All @@ -20,7 +19,7 @@ Java_com_baiiu_jnitest_testSocket_TestSocketFragment_native_1connect(JNIEnv *env
__android_log_print(ANDROID_LOG_ERROR, "mLogU", "start connect: %p, %p", &env, env);

// int result = function(1000000000);
int result = function(5);
int result = fibonacci(5);

__android_log_print(ANDROID_LOG_ERROR, "mLogU", "end connect: %p, %p, %d", &env, env, result);
return true;
Expand Down
8 changes: 5 additions & 3 deletions jni/jnitest/src/main/java/com/baiiu/jnitest/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.os.Bundle;

import com.baiiu.jnitest.bitmap.BitmapFragment;
import com.baiiu.jnitest.dlopen.DLOpenFragment;
import com.baiiu.jnitest.exception.ExceptionFragment;
import com.baiiu.jnitest.reference.PassReferenceFragment;
import com.baiiu.jnitest.reference.ReferenceFragment;
Expand All @@ -21,8 +22,7 @@ public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);



getSupportFragmentManager().beginTransaction()
.replace(R.id.container, getFragment())
.commitAllowingStateLoss();
Expand Down Expand Up @@ -54,7 +54,9 @@ private Fragment getFragment() {

// return new BitmapFragment();

return new TestSocketFragment();
// return new TestSocketFragment();

return new DLOpenFragment();

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
Expand All @@ -14,7 +13,7 @@
* time: 2020/12/16
* description:
*/
public class HomeActivity extends AppCompatActivity {
public class SplashActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
Expand All @@ -29,7 +28,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(HomeActivity.this, MainActivity.class));
startActivity(new Intent(SplashActivity.this, MainActivity.class));
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.baiiu.jnitest.dlopen;

import android.text.TextUtils;

import com.baiiu.jnitest.base.BaseFragment;
import com.baiiu.jnitest.testSocket.TestSocketFragment;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import dalvik.system.BaseDexClassLoader;

/**
* author: baiiu
* time: 2020/12/24
* description:
*/
public class DLOpenFragment extends BaseFragment {

static {
System.loadLibrary("dlopen-lib");
}

@Override
protected void initOnCreateView() {
try {
Method findLibrary = BaseDexClassLoader.class.getDeclaredMethod("findLibrary", String.class);
findLibrary.setAccessible(true);

BaseDexClassLoader dexPathClassLoader = (BaseDexClassLoader) TestSocketFragment.class.getClassLoader();
String targetSoAbsolutePath = dexPathClassLoader.findLibrary("socket-lib");
android.util.Log.e("mLogU", "ClassLoader#findLibrary: " + targetSoAbsolutePath);

} catch (Exception e) {
android.util.Log.e("mLogU", e.toString());
}


try {
Field pathListF = BaseDexClassLoader.class.getDeclaredField("pathList");
pathListF.setAccessible(true);
ClassLoader dexPathClassLoader = TestSocketFragment.class.getClassLoader();
Object pathList = pathListF.get(dexPathClassLoader);

Field nativeLibraryPathElementsF = Class.forName("dalvik.system.DexPathList").getDeclaredField("nativeLibraryPathElements");
nativeLibraryPathElementsF.setAccessible(true);
Object nativeLibraryPathElements = nativeLibraryPathElementsF.get(pathList);
android.util.Log.e("mLogU", nativeLibraryPathElements.toString());

// find the nativeLibraryPathElements
Object[] arr = (Object[]) nativeLibraryPathElements;
for (Object o : arr) {
android.util.Log.e("mLogU", o.toString());
}


Field pathF = Class.forName("dalvik.system.DexPathList$NativeLibraryElement").getDeclaredField("path");
pathF.setAccessible(true);

String targetSoAbsolutePath = null;
for (Object o : arr) {
File path = (File) pathF.get(o);
targetSoAbsolutePath = findNativeLibrary(path, "libsocket-lib.so");
if (!TextUtils.isEmpty(targetSoAbsolutePath)) {
break;
}
}

testdlopen(targetSoAbsolutePath);

} catch (Exception e) {
android.util.Log.e("mLogU", e.toString());
}

}


private native void testdlopen(String targetSoAbsolutePath);


public String findNativeLibrary(File path, String name) {
File file = new File(path, name);
android.util.Log.e("mLogU", file.getAbsolutePath());

if (file.exists()) {
return file.getAbsolutePath();
}

return null;
}


}

0 comments on commit 031644c

Please sign in to comment.