0

我正在尝试编写一个程序来调用我在 Android 中的 .so 库中的函数。

主.cpp:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

typedef int (*test_ptr)(int, int);

int main()
{
    int rc;
    void *handle;
    const char *error;

    handle = dlopen("./testdll.so", RTLD_LAZY);
    if(!handle){
        printf("dlopen %s\n", dlerror());
        return -1;
        }
    printf("dlopen success.\n");

    test_ptr test = (test_ptr)dlsym(handle, "max");
    error = dlerror();
    if (error)  {
        printf("error %s\n", error);
        dlclose(handle);
        return -1;
    }
    rc = test(10, 20);
    printf("rc = %d\n", rc);

    dlclose(handle);
    return 1;
}

测试dll.cpp:

#include<stdio.h>

int max(int x,int y){
    return x>y?x:y;
}

安卓.mk:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
    testdll.cpp
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := true
LOCAL_LDFLAGS := -Wl,--export-dynamic
LOCAL_MODULE:= testdll
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
    main.cpp
LOCAL_LDLIBS := -ldl
LOCAL_SHARED_LIBRARIES := \
libcutils   \
libdl
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := true
LOCAL_MODULE := mytest
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
include $(BUILD_EXECUTABLE)

我使用mmm制作文件并将testdll.so推入/system/lib并将mytest推入/data/data

然后我运行./mytest,它可以打开 testdll.so succeeded ,但无法连接我的功能。

错误是:

Symbol not found:

有人知道如何解决这个问题吗?

==================================================== =========================================

谢谢大家!

我称我的函数成功使用extern "C"

但是现在,我改用 C++ 编写 .so 库并得到相同的错误消息。

测试dll.cpp:

#include <sys/types.h>
#include <unistd.h>
#include <grp.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>

#include <private/android_filesystem_config.h>

#include <stdio.h>
#include "testdll.h"

using namespace android;
extern "C" {
    int TestClass::max(int x,int y){
        return x>y?x:y;
    }
}

测试dll.h:

using namespace android;

class TestClass
{
    public:
        int max(int, int);
};

主.h:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

typedef int (*test_ptr)(int, int);

int main()
{
    int rc;
    void *handle;
    const char *error;

    handle = dlopen("./testdll.so", RTLD_LAZY);
    if(!handle){
        printf("dlopen %s\n", dlerror());
        return -1;
    }
    printf("dlopen success.\n");

    test_ptr test = (test_ptr)dlsym(handle, "max");
    error = dlerror();
    if (error)  {
        printf("error %s\n", error);
        dlclose(handle);
        return -1;
    }
    rc = test(10, 20);
    printf("rc = %d\n", rc);

    dlclose(handle);
    return 1;
}

然后我得到了同样的错误信息:找不到符号:

我使用 objdump -TC 来显示:

DYNAMIC SYMBOL TABLE:
000003f5 g    DF .text  0000000a TestClass::max(int, int)
00000000      DF *UND*  00000000 __aeabi_unwind_cpp_pr0
00000000      DF *UND*  00000000 __cxa_finalize
000010f0 g    D  .bss   00000000 __dso_handle
00001000 g    D  .init_array    00000000 __INIT_ARRAY__
00001008 g    D  .fini_array    00000000 __FINI_ARRAY__
00000410 g    D  *ABS*  00000000 __exidx_end
00000400 g    D  *ABS*  00000000 __exidx_start
000010ec g    D  *ABS*  00000000 __data_start
000010ec g    D  *ABS*  00000000 _edata
000010ec g    D  *ABS*  00000000 __bss_start
000010ec g    D  *ABS*  00000000 __bss_start__
00001100 g    D  *ABS*  00000000 _bss_end__
00001100 g    D  *ABS*  00000000 __bss_end__
00001100 g    D  *ABS*  00000000 __end__
00001100 g    D  *ABS*  00000000 _end
00080000 g    D  *ABS*  00000000 _stack

我该如何修改?

再次感谢!

4

2 回答 2

2

TestClass::max(int, int) 在你的符号表中 - 这是否意味着你的 max 函数是一个类的方法?

好吧,如果是这样,您需要为您的 TestClass 创建一个 C 包装,例如

extern "C"
{
    int max (void *pHandle, int x, int y) 
    {
      TestClass *tcObject = (TestClass *)pHandle;
      return tcObject->max(x, y);
    }
}
于 2012-07-12T04:26:20.727 回答
1

dlopen必须声明您计划通过其访问的任何函数extern "C"。原因是名称混乱

于 2012-07-12T02:28:26.540 回答