最近项目需要提升所有 Python 算法的执行时间,并给 Java 框架调用,根据 Python一键转Jar包,Java调用Python新姿势!的思路可以用 Cython 将 Python 代码转换为 C 代码再编译为动态连接库 (so / dll),提升 Python 代码执行速度。同时提供 Java Native 接口以供 Java 框架调用。

问题

但在根据刚刚所提博文进行复现时,出现了一个老大难问题,一直都没什么头绪

Exception in thread "main" java.lang.UnsatisfiedLinkError: /path/libTest.cpython-36m-x86_64-linux-gnu.so: /path/libTest.cpython-36m-x86_64-linux-gnu.so: undefined symbol: PyInit_Test
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at Test.<clinit>(Test.java:6)
at Demo.main(Demo.java:3)

直到看到这篇博客 解決 Linux 上 C/C++ 的 undefined symbol 或 undefined reference,可以通过 nm -D LIBRARY_FILE 来查看动态代码段的相关符号 (symbol),输出信息如下

0000000000004a10 T Java_Test_uninitModule
0000000000004a20 T Java_Test_upperFunction
......
U PyImport_ImportModule
U PyInit_Test
00000000000042e7 T PyInit_libTest
......

其中,T 表示全局/局部符号,U 表示为未定义的符号。

原因

也就是说,这个 PyInit_Test 函数未定义,但 PyInit_libTest 却定义了,明明在 main.c 中没有定义这个lib函数,唯一出现的地方就是在编译文件 setup.py

extensions = [Extension("libTest", sourcefiles,
include_dirs=['/usr/lib/jvm/java-8-oracle/include/',
'/usr/lib/jvm/java-8-oracle/include/linux/',
'/python/path/include/python3.6m/'],
library_dirs=['/python/path/lib/'],
libraries=['python3.6m'])]

第一个参数是 name,表示的是这个 extension 的全称,而之后的调用就会依托这个名字,同时在 main.cPyInit_ 之后接的是该模块的名称。也就是说,当这两个名称相同的时候,Cython 才能成功编译这个模块。

解决方案

因此将参数 name"libTest" 替换为 "Test",问题解决。

重新用 nm -D Test.so 来查看,可以看到 PyInit_Test这个函数已定义,收工~

00000000000042b7 T PyInit_Test

JNI调用Cython生成库‘undefined symbol: PyInit_’问题的更多相关文章

  1. JAVA程序通过JNI调用C/C++库

    java程序如何调用c/c++库中的函数主要分为三个步骤: 1. 加载库文件. System.loadLibrary 2. 找到函数( java函数<----映射---->c函数 ) 3. ...

  2. Linux 动态库 undefined symbol 原因定位与解决方法

    在使用动态库开发部署时,遇到最多的问题可能就是 undefined symbol 了,导致这个出现这个问题的原因有多种多样,快速找到原因,采用对应的方法解决是本文写作的目的. 可能的原因 依赖库未找到 ...

  3. JNI调用so动态库

    1.编写native接口 package org.demo; public class JniDemo { public static native int bmp2fea(byte[] bmp, b ...

  4. Java採用JNI调用VC++生成的dll(Java与C++交互)

    应项目需求,须要android调用java,java再调用C++实现android一个图片匹配的功能,我们作为java组须要和C++和Android进行交互.以下是java和C++採用JNI的方式进行 ...

  5. java调用c++生成的动态和静态库时遇到的问题

    java.lang.UnsatisfiedLinkError: no jacob in java.library.path -Djava.library.path 关于java用jni调用 dll动态 ...

  6. [置顶] android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so

    0:前言: 在第二篇中,我们主要介绍了丙方android公司利用乙方C++公司给的动态库,直接调用库中的方法,但是这样方式受限于: 乙方C++公司开发的动态库是否符合jni的规范,如果不规范,则不能直 ...

  7. 利用android studio 生成 JNI需要的动态库so文件

    JNI:  Java Native Interface,  提供了java语言和其他语言(例如c和c++)进行相互调用的方式. 本文是用java调用c生成的so模式.其中,编译so文件过程如下: 1) ...

  8. c++调用matlab生成的Dll动态连接库

    点击打开链接http://download.csdn.net/detail/nuptboyzhb/4228429 c++调用matlab生成的Dll动态连接库 实验平台:   matlab 7.0(R ...

  9. [置顶] android利用jni调用第三方库——第二篇——编写库android程序直接调用第三方库libhello.so

    0:前言 1:本文主要作为丙方android公司的身份来写 2:作者有不对的地方,请指出,谢谢 [第一篇:android利用jni调用第三方库——编写库libhello.so] [第二篇:androi ...

随机推荐

  1. Sublime Text3 注册码(Windows/Build 3176版本)| 开发工具

    转自:dushusir.com 1.修改hosts文件(路径:C:\Windows\System32\drivers\etc): 0.0.0.0 www.sublimetext.com 0.0.0.0 ...

  2. 从0开始探究vue-双向绑定原理

    理解 vue是一个非常优秀的框架,其优秀的双向绑定原理,mvvm模型,组件,路由解析器等,非常的灵活方便,也使开发者能够着重于数据处理,让开发者更清晰的设计自己的业务. 双向绑定,就是数据变化的时候, ...

  3. Ftrace的部分使用方法

    ftrace主要是用于调试linux kernel调度相关的一个工具,也可用于分析部分kernel性能问题. 相关ftrace的介绍可以参考:kernel/msm-4.9/Documentation/ ...

  4. Java实现 蓝桥杯VIP 算法训练 字符串逆序

    问题描述 给定一个字符串,将这个串的所有字母逆序后输出. 输入格式 输入包含一个字符串,长度不超过100,字符串中不含空格. 输出格式 输出包含一个字符串,为上面字符串的逆序. 样例输入 tsinse ...

  5. Java实现 LeetCode 290 单词规律

    290. 单词规律 给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律. 这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非 ...

  6. Java实现蓝桥杯单位转换

    单位转换 [问题描述] BobLee最近在复习考研,在复习计算机组成原理的时候,遇到了一个问题.就是在计算机存储里面的单位转换. 我们都知道1MB=1024KB,1KB=1024B,1B=8bit,他 ...

  7. Java实现 LeetCode 42 接雨水

    42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这 ...

  8. java实现第八届蓝桥杯树型显示

    树型显示 题目描述 对于分类结构可以用树形来形象地表示.比如:文件系统就是典型的例子. 树中的结点具有父子关系.我们在显示的时候,把子项向右缩进(用空格,不是tab),并添加必要的连接线,以使其层次关 ...

  9. WPF 学习(一)

    一.WPF介绍 WPF全称 Windows Presentation Foundation,干啥用的? 主要是用来制作Windows桌面客户端软件的. .Net平台下制作Windows桌面客户端软件主 ...

  10. [go设计模式]工厂方法模式

    简单工厂就是生产整个计算器,而工厂方法只生产计算器的一部分: 原有的简单工厂可以生'+' '-' '*' '/' ;但是如果添加新的部件'%',厂房就 需要扩充.修改很可以会影响原来部件的正常生产,这 ...