Skip to content

ctypes.util.find_library 64-bit error #2468

Closed
@macdems

Description

@macdems

I was trying to use zeroconf package for my application. It worked perfectly on armeabi-v7a, however the program crashed on launch on arm64-v8a (both tested on Huawei P30).

I have investigated the issues and discovered that the problem is with ctypes.util.find_library or, more precisely with the p4a module andoroid._ctypes_library_finder in the function find_library.

The actual problem is that this function finds 32bit libraries regardless of the actual architecture. For example

ctypes.util.find_library('c')

returns /system/lib/libc.so both for 32- and 64-bit architecture. The correct behavior is to return this if Python is compiled for 32-bit and /system/lib64/libc.so for 64-bit one.

Below is the code of a simple Kivy app that shows the issue:

# main.py
import sys
import ctypes


from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label


root = Builder.load_string("""\
#:import sys sys

BoxLayout:
    orientation: 'vertical'
    Label:
        id: arch
        size_hint_y: 1
        text_size: self.size
        halign: 'center'
        valign: 'middle'
        text: '64-bit' if sys.maxsize > 2**32 else '32-bit'
    Label:
        id: lib
        size_hint_y: 1
        text_size: self.size
        halign: 'center'
        valign: 'middle'
    Label:
        id: err
        size_hint_y: 4
        text_size: self.size
        halign: 'left'
        valign: 'middle'
""")


class TestCtypesApp(App):

    def build(self):
        lib = ctypes.util.find_library('c')
        root.ids.lib.text = str(lib)
        try:
            cdll = ctypes.CDLL(lib)
        except Exception as err:
            root.ids.err.text = "{}: {}".format(type(err).__name__, err)
        else:
            root.ids.err.text = 'CORRECT'
            root.ids.err.halign = 'center'
        return root


if __name__ == '__main__':
    TestCtypesApp().run()
# buildozer.spec
[app]
title = Test CTypes
package.name = testctypes
package.domain = org.test
source.dir = .
source.include_exts = py
version = 0.1
requirements = python3,kivy
orientation = portrait
osx.python_version = 3
osx.kivy_version = 1.9.1
fullscreen = 0
android.api = 30
android.arch = armeabi-v7a
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.7.0

[buildozer]
log_level = 2
warn_on_root = 1

[app@arm64]
android.arch = arm64-v8a

When compiled for armeabi-v7a it shows:

32-bit

/system/lib/libc.so

CORRECT

while on arm64-v8a:

64-bit

/system/lib/libc.so

OSError: dlopen failed: library "/system/lib/libc.so" needed or dlopened by
"/data/data/org.test.testctypes/files/app/_python_bundle/modules/_ctypes.cpython-38.so"
is not accessible for this namespace "classloader-namespace"

The expected output is:

64-bit

/system/lib64/libc.so

CORRECT

The source of this problem is in the line 47 of the file pythonforandroid/recipes/android/src/android/_ctypes_library_finder.py. For 64-bit Python (build target arch matters, not the system archiecture), the libraries to search should be ["/system/lib64/libc.so", "/system/lib/libc.so"].

I am also submitting a pull request resolving this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions