简体   繁体   中英

Python: Building a C++ Module in Anaconda (Windows) as a shared object and not as an extension

Suppose you have a C++ function that you want to use with python in the file "fun.cpp"

extern "C" int fun(int i)
{
    return i*2;
}

Then you could use the following "setup.py"

from distutils.core import setup, Extension

module1 = Extension('fun', sources = ['src/fun.cpp'],include_dirs = ['src/'])

setup (name = 'fun',
        version = '1.0',
        description = 'This is a fun package',
        ext_modules = [module1],
        packages = ['fun'])

Then in the fun package you could have the following __init__.py

import ctypes   
fun = ctypes.cdll.LoadLibrary(__path__[0]+"/../fun.so").fun
fun.restype = ctypes.c_int
fun.argtype = ctypes.c_int

So you can use it like

>>import fun
>>fun.fun(2)
>>4

:)

This works perfect in Linux, but when I tried this on Windows with Anaconda, first the linker ask me for a initfun symbol, which means that it is trying to build a python extension instead of just building a shared object. Does anybody know how to change the setup.py or the Anaconda settings just to build a shared object and use it with the "ctypes.cdll.LoadLibrary" function?

Thanks in advance.

I finally use this solution. Is not as clean as it could be, as it tries to find the Anaconda path in a not safe way.

from distutils.core import setup, Extension

from sys import platform as _platform
if _platform == "linux" or _platform == "linux2":
    module1 = Extension('fun/fun', sources = ['src/fun.cpp','src/cochlea.cpp'],include_dirs = ['src/'], extra_compile_args=['-Ofast','-flto','-march=native','-funroll-loops'] )
    setup (name = 'fun',
        version = '1.0',
        description = 'This is a demo package',
        ext_modules = [module1],
        packages = ['fun'])

elif _platform == "darwin":
    module1 = Extension('fun/fun', sources = ['src/fun.cpp','src/cochlea.cpp'],include_dirs = ['src/'], extra_compile_args=['-Ofast','-flto','-march=native','-funroll-loops'] )
    setup (name = 'fun',
        version = '1.0',
        description = 'This is a demo package',
        ext_modules = [module1],
        packages = ['fun'])

elif _platform == "win32":


    import sys
    for a in sys.path:
        f = a.find('Anaconda')
        if f!=-1:
            path = a[:f+9]

    import os

    os.system("gcc.bat -mdll -O -Wall -Isrc/ -I"+path+"include -I"+path+"PC -c src/fun.cpp -o fun.o -Ofast -flto -march=native -funroll-loops") 
    os.system("g++.bat -shared -s fun.o -o fun.dll") 

    setup (name = 'fun',
            version = '1.0',
            description = 'This is a demo package',
            package_data={'fun': ['fun.dll']},
            packages = ['fun'])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM