首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Cython调用JUCE?

如何使用Cython调用JUCE?
EN

Stack Overflow用户
提问于 2017-07-30 18:31:26
回答 1查看 142关注 0票数 0

目前,我正试图让JUCE音频框架从Cython中运行。因此,我首先希望通过通过JUCE框架显示一个AlertWindow来获得一个小的简单示例,但目前我似乎遇到了两个小问题: 1.调用JUCE框架2中的枚举存在问题。我不知道如何包含用于编译和链接的整个框架。

My setup.py (名为"python3 setup.py build_ext -inplace“):

代码语言:javascript
复制
# Cython compile instructions
from setuptools import setup
from setuptools.extension import Extension
from Cython.Build import cythonize


compile_args = ['-g', '-std=c++11', '-stdlib=libc++']

extensions = [Extension('testb', ['src/JUCE/testb.pyx'],
            extra_compile_args=compile_args,
            include_dirs = ["JUCE/modules"],)]

setup(
    name='My app',
    ext_modules=cythonize(extensions)
)

我的testb.pyx (问题1在这里):

代码语言:javascript
复制
# distutils: language = c++

cdef extern from "JuceLibraryCode/JuceHeader.h" namespace "juce":
    cdef cppclass AlertWindow:
        AlertWindow(String, String, AlertIconType)

cdef class PyAlertWindow:
    cdef AlertWindow *thisptr
    def __cinit__(self):
        self.thisptr = new AlertWindow("", "", NoIcon) # Don't know how to call the enum right here
    def __dealloc__(self):
        del self.thisptr
    @staticmethod
    def showAlertWindow(b):
        print("at least this works")

此外,我不断地得到这些类型的错误,据我所知,这些错误是由于框架的其他部分没有编译和包含/链接造成的。我该怎么做?

代码语言:javascript
复制
ImportError:
dlopen(<project root>/build/lib/testb.cpython-36m-darwin.so, 2): Symbol not found: __ZN4juce6StringC1Ev
Referenced from:
<project root>/build/lib/testb.cpython-36m-darwin.so
Expected in: flat namespace
in <project root>/build/lib/testb.cpython-36m-darwin.so

此外,使用--inplace标志,所有已编译的文件都会被转储到我的主文件夹中,这看起来不太适合扩展,特别是在更大的框架中。我如何确保所有的. so -文件都在其中,这样就可以很容易地引用它们?还是有更好的方法来处理这件事?

好的,在@ead的帮助下,我能够更进一步。代码现在看起来如下:

代码语言:javascript
复制
# setup.py

from setuptools import setup
from setuptools.extension import Extension
from Cython.Build import cythonize

compile_args = ['-g', '-std=c++11', '-stdlib=libc++']

extensions = [Extension('testb', ['src/program/testb.pyx'],
                extra_compile_args=compile_args,
                include_dirs = ["JUCE/modules"],
                libraries=["NewProject"], #the name of your library, WHICH MIGHT BE DIFFERENT FROM THE FILENAME!
                library_dirs=["src/program/JuceLibraryCode"] #where your library is placed.

                    )]

setup(
    name='My app',
    ext_modules=cythonize(extensions)
)

我的Cython文件:

代码语言:javascript
复制
# testb.pyx
# distutils: language = c++

from libcpp.string cimport string

cdef extern from "JuceLibraryCode/JuceHeader.h":
    cdef cppclass AlertWindow:
        AlertWindow(String, String, AlertIconType, Component*)

    cdef cppclass Component:
        Component()

    cdef cppclass String:
        String(string)

cdef extern from "JuceLibraryCode/JuceHeader.h" namespace    "juce::AlertWindow":
    ctypedef enum AlertIconType:
        NoIcon
        QuestionIcon
        WarningIcon
        InfoIcon

cdef class PyAlertWindow:
    cdef AlertWindow *thisptr
    def __cinit__(self):
        self.thisptr = new AlertWindow(String(""), String(""), AlertIconType(NoIcon), NULL)
    def __dealloc__(self):
        del self.thisptr

这个例子现在编译得很好。但是,当我导入结果包时,我会得到以下错误:

代码语言:javascript
复制
ImportError: dlopen(<project root>/testb.cpython-36m-darwin.so, 2): Symbol not found: _CGAffineTransformIdentity
  Referenced from: <project root>/testb.cpython-36m-darwin.so
  Expected in: flat namespace
 in <project root>/testb.cpython-36m-darwin.so

这似乎与可可(在这里)或CoreGraphics (在这里)有关(我也认为Cocoa是可可的继承者)。那我该怎么解决呢?我是否需要包括框架CoreGraphics,如果需要,如何包括?(只需简单地添加-framework CoreGraphics标志,就会产生clang: CoreGraphics:未知参数:'-framework CoreGraphics‘。)

提前感谢您的回答!

EN

回答 1

Stack Overflow用户

发布于 2017-07-31 04:16:28

对于您的第一个问题:如果您的枚举和函数定义为

代码语言:javascript
复制
//YYY.h
namespace Foo{
  enum Bar {bar1, bar2};
  void do_it(Bar bar);
}

然后,您需要在cython中导入enum-值以及enum-type名称,它应该如下所示:

代码语言:javascript
复制
cdef extern from 'XXX/YYY.h' namespace 'Foo':
    ctypedef enum Bar:
      bar1
      bar2
    cpdef void do_it(Bar a)

然后,可以通过do_it(bar1)do_it(bar2)在您的cython代码中调用它。事实上,我是在不久前从这个问题在这里如此那里学到的,所以你可以考虑投票。

第二个问题是,您需要链接到juce库(现在只使用包含),为此,需要在扩展设置中添加以下内容:

代码语言:javascript
复制
Extension('testb', ['src/JUCE/testb.pyx'], ...
          libraries=[juce],#here the right name on your system
          library_dirs=[PATH_TO_JUCE_LIB_ON_YOUR_SYSTEM]
         }

PS:如果你不喜欢内置选项的结果,请咨询distutils文档的替代方案。

编辑:JUCE还有一些需要提供给链接器的其他依赖项。我认为最好的方法是为您的系统构建一个c++示例(例如HelloWorld),并查看需要哪些库。

通过查看Linux上的Makefile,似乎至少需要以下库:freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0。也许你甚至需要先安装他们,我不认为他们是默认的每一个系统。

那么您的设置应该如下所示:

代码语言:javascript
复制
Extension('testb', ['src/JUCE/testb.pyx'], ...
          libraries=['juce', 'x11', 'freetype2', ...], #all needed libraries
          library_dirs=[PATH_TO_JUCE, '/usr/X11R6/lib', '/usr/lib', ...] #all needed library paths
         }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45403273

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档