পাইথন থেকে সি / সি ++ কল করা হচ্ছে?


520

সি বা সি ++ গ্রন্থাগারের সাথে পাইথন বাঁধাইয়ের দ্রুততম উপায় কী হবে?

(আমি যদি উইন্ডোজটি ব্যবহার করি তবে এটি গুরুত্বপূর্ণ))

উত্তর:


169

বুস্ট.পাইথনটিতে আপনার নজর রাখা উচিত । এখানে তাদের ওয়েবসাইট থেকে নেওয়া সংক্ষিপ্ত ভূমিকা:

বুস্ট পাইথন লাইব্রেরি পাইথন এবং সি ++ ইন্টারফেস করার জন্য একটি কাঠামো। এটি আপনাকে সিথ ++ ক্লাস ফাংশন এবং অবজেক্টগুলিকে পাইথন এবং তদ্বিপরীতভাবে কোনও বিশেষ সরঞ্জাম ব্যবহার না করে - কেবল আপনার সি ++ সংকলকটি দ্রুত এবং নির্বিঘ্নে প্রকাশ করতে দেয়। এটি সি ++ ইন্টারফেসগুলি অ-প্রবেশমূলকভাবে মোড়ানোর জন্য ডিজাইন করা হয়েছে, যাতে এটি মোড়ানোর জন্য আপনাকে সি ++ কোডটি কোনও পরিবর্তন করতে হবে না, পাইথনে তৃতীয় পক্ষের লাইব্রেরিগুলি প্রকাশ করার জন্য বুস্ট.পাইথনকে আদর্শ করে তুলুন। গ্রন্থাগারের উন্নত রূপক কৌশলগুলির ব্যবহার ব্যবহারকারীদের জন্য এর বাক্য গঠনটিকে সহজতর করে, যাতে মোড়ানোর কোডটি এক ধরণের ডিক্যারেটিভ ইন্টারফেস সংজ্ঞা ভাষা (আইডিএল) দেখে।


বুস্ট.পিথন বুস্টের আরও ব্যবহারকারী-বান্ধব লাইব্রেরিগুলির মধ্যে একটি, একটি সাধারণ ফাংশন কল এপিআইয়ের জন্য এটি বেশ সোজা এবং এটি আপনাকে নিজের লিখতে হবে এমন বয়লারপ্লেট সরবরাহ করে। আপনি যদি কোনও অবজেক্ট ভিত্তিক এপিআই প্রকাশ করতে চান তবে এটি কিছুটা জটিল।
jwfearn

15
বুস্ট.পিথন সবচেয়ে খারাপ জিনিস যা কল্পনাযোগ্য। প্রতিটি নতুন মেশিনের জন্য এবং প্রতিটি আপগ্রেডের সাথে এটি লিঙ্কিংয়ের সমস্যার সাথে চলে।
মিলার

14
প্রায় 11 বছর পরে এই উত্তরের মান সম্পর্কে কিছু চিন্তাভাবনা করার জন্য?
জে ইভান্স

4
এটি এখনও ইন্টারফেস অজগর এবং সি ++ সেরা পদ্ধতির?
tushaR

8
সম্ভবত আপনি পাইবাইন্ড 11 চেষ্টা করতে পারেন যা বুস্টের তুলনায় লাইটওয়েট।
jdhao

658

ctypes মডিউল মান লাইব্রেরির অংশ, এবং সেইজন্য আরো স্থিতিশীল চেয়ে প্রচুর পাওয়া যায় টানা , যা সবসময় আমাকে দিতে সেদিকেই ঝুঁকেছে সমস্যার

টাইপসের সাহায্যে আপনাকে পাইথনের উপর যে কোনও সংকলন সময় নির্ভরতা পূরণ করতে হবে এবং আপনার বাইন্ডিংয়ের সাথে সিটিপস রয়েছে এমন কোনও অজগরটির উপর কাজ করবে, কেবল তার বিরুদ্ধে সংকলিত ছিল না।

ধরুন আপনার একটি সাধারণ সি ++ উদাহরণ বর্গ রয়েছে যার সাথে আপনি foo.cpp নামক একটি ফাইলে কথা বলতে চান:

#include <iostream>

class Foo{
    public:
        void bar(){
            std::cout << "Hello" << std::endl;
        }
};

যেহেতু সিটিপস কেবল সি ফাংশনগুলির সাথে কথা বলতে পারে, তাই আপনাকে তাদের বহিরাগত "সি" হিসাবে ঘোষণা করে এমনগুলি সরবরাহ করতে হবে

extern "C" {
    Foo* Foo_new(){ return new Foo(); }
    void Foo_bar(Foo* foo){ foo->bar(); }
}

এর পরে আপনাকে এটি একটি ভাগ করা লাইব্রেরিতে সংকলন করতে হবে

g++ -c -fPIC foo.cpp -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so  foo.o

এবং অবশেষে আপনাকে আপনার অজগর র‌্যাপারটি লিখতে হবে (উদাহরণস্বরূপ fooWrapper.py এ)

from ctypes import cdll
lib = cdll.LoadLibrary('./libfoo.so')

class Foo(object):
    def __init__(self):
        self.obj = lib.Foo_new()

    def bar(self):
        lib.Foo_bar(self.obj)

একবার আপনার কাছে থাকলে আপনি এটি পছন্দ করতে পারেন

f = Foo()
f.bar() #and you will see "Hello" on the screen

14
এটি একক ফাংশন কলে আপনার জন্য বুস্ট.পিথন যা করে তা অনেকটাই।
মার্টিন বেকেট

201
সিটিপস পাইথন স্ট্যান্ডার্ড লাইব্রেরিতে রয়েছে, সুইগ এবং বুস্ট হয় না। সুইগ এবং বুস্ট এক্সটেনশন মডিউলগুলিতে নির্ভর করে এবং অতএব পাইথন ছোটখাটো সংস্করণে আবদ্ধ হয় যা নির্বিচারে ভাগ করা বস্তু নয়। একটি সুইগ বা বুস্ট মোড়ক তৈরি করা ব্যথা হতে পারে, সিটিপস কোনও বিল্ড প্রয়োজনীয়তা তৈরি করে না।
ফ্লোরিয়ান বুশ

25
বুস্ট ভুডো টেম্পলেট যাদু এবং সম্পূর্ণ কাস্টম বিল্ড সিস্টেমের উপর নির্ভর করে, সিটিপস সরলতার উপর নির্ভর করে। সিটিপস গতিশীল, বুস্ট স্থির। সিটিপস লাইব্রেরির বিভিন্ন সংস্করণ পরিচালনা করতে পারে। বুস্ট করতে পারে না।
ফ্লোরিয়ান বুশ

32
উইন্ডোজে পাইথনের সেগুলি দেখতে সক্ষম হবার জন্য আমাকে আমার ফাংশন স্বাক্ষরে __declspec (dllexport) নির্দিষ্ট করতে হয়েছিল। উপরের উদাহরণ থেকে এটি এর সাথে মিলিত হবে: extern "C" { __declspec(dllexport) Foo* Foo_new(){ return new Foo(); } __declspec(dllexport) void Foo_bar(Foo* foo){ foo->bar(); } }
অ্যালান ম্যাকডোনাল্ড

13
একটি প্রদানের যেমন দ্বারা পরে পয়েন্টার মুছে ফেলতে ভুলবেন না Foo_deleteফাংশন এবং একটি পাইথন বিনাশকারী থেকে হয় এটিকে কলিং বা বস্তুর মোড়কে রিসোর্স
অ্যাডভারসাস

57

এই কাজ করতে দ্রুততম উপায়ে ব্যবহার করছে টানা

SWIG টিউটোরিয়াল থেকে উদাহরণ :

/* File : example.c */
int fact(int n) {
    if (n <= 1) return 1;
    else return n*fact(n-1);
}

ইন্টারফেস ফাইল:

/* example.i */
%module example
%{
/* Put header files here or function declarations like below */
extern int fact(int n);
%}

extern int fact(int n);

ইউনিক্সে পাইথন মডিউল তৈরি করা:

swig -python example.i
gcc -fPIC -c example.c example_wrap.c -I/usr/local/include/python2.7
gcc -shared example.o example_wrap.o -o _example.so

ব্যবহার:

>>> import example
>>> example.fact(5)
120

মনে রাখবেন আপনার অজগর-দেব থাকতে হবে। এছাড়াও কয়েকটি সিস্টেমে পাইথন শিরোনাম ফাইলগুলি আপনি এটি ইনস্টল করেছেন তার উপর ভিত্তি করে /usr/incolve/python2.7 এ থাকবে।

টিউটোরিয়াল থেকে:

এসডব্লিউআইজি প্রায় প্রতিটি ভাষার বৈশিষ্ট্য সমর্থন করে মোটামুটি সম্পূর্ণ সি ++ সংকলক। এর মধ্যে রয়েছে প্রিপ্রোসেসিং, পয়েন্টার, ক্লাস, উত্তরাধিকার এবং এমনকি সি ++ টেম্পলেট। এসডাব্লুআইজি লক্ষ্য ভাষায় কাঠামো এবং ক্লাসগুলিকে প্রক্সি ক্লাসে প্যাকেজ করতেও ব্যবহার করা যেতে পারে - খুব স্বাভাবিক পদ্ধতিতে অন্তর্নিহিত কার্যকারিতাটি প্রকাশ করে।


49

আমি উচ্চতর স্তরের তথ্য প্রকারের (পাইথনের তালিকার সাথে বহুমাত্রিক এসটিএল ভেক্টর) লিঙ্ক করার উদ্দেশ্য নিয়ে এই পৃষ্ঠাটি থেকে পাইথন <-> সি ++ বাইন্ডিংয়ে আমার যাত্রা শুরু করেছি :-)

সিটিইপস এবং বুস্ট.পাইথন উভয়ের উপর ভিত্তি করে সমাধানগুলি চেষ্টা করে (এবং সফটওয়্যার ইঞ্জিনিয়ার না হয়ে) যখন উচ্চ স্তরের ডেটাটাইপস বাঁধাইয়ের প্রয়োজন হয় তখন আমি এগুলিকে জটিল বলে মনে করেছি, যখন আমি এসডিজিআইজি এই জাতীয় ক্ষেত্রে খুব বেশি সহজ পেয়েছি ।

এই উদাহরণটি তাই SWIG ব্যবহার করে, এবং এটি লিনাক্সে পরীক্ষা করা হয়েছে (তবে এসডিজিআইজি উপলব্ধ এবং উইন্ডোজেও এটি ব্যাপকভাবে ব্যবহৃত হয়)।

উদ্দেশ্যটি পাইথনের কাছে একটি সি ++ ফাংশন উপলব্ধ করা যা 2D এসটিএল ভেক্টর আকারে একটি ম্যাট্রিক্স গ্রহণ করে এবং প্রতিটি সারির গড় ফিরে আসে (1D এসটিএল ভেক্টর হিসাবে)।

সি ++ ("কোড.cpp") এ কোডটি নিম্নরূপ:

#include <vector>
#include "code.h"

using namespace std;

vector<double> average (vector< vector<double> > i_matrix) {

  // Compute average of each row..
  vector <double> averages;
  for (int r = 0; r < i_matrix.size(); r++){
    double rsum = 0.0;
    double ncols= i_matrix[r].size();
    for (int c = 0; c< i_matrix[r].size(); c++){
      rsum += i_matrix[r][c];
    }
    averages.push_back(rsum/ncols);
  }
  return averages;
}

সমমানের শিরোনাম ("কোড.h") হ'ল:

#ifndef _code
#define _code

#include <vector>

std::vector<double> average (std::vector< std::vector<double> > i_matrix);

#endif

আমরা প্রথমে একটি অবজেক্ট ফাইল তৈরি করতে সি ++ কোডটি সংকলন করি:

g++ -c -fPIC code.cpp

তারপরে আমরা আমাদের সি ++ ফাংশনের জন্য একটি এসডব্লিউআইজি ইন্টারফেস সংজ্ঞা ফাইল ("কোড.i") সংজ্ঞায়িত করি ।

%module code
%{
#include "code.h"
%}
%include "std_vector.i"
namespace std {

  /* On a side note, the names VecDouble and VecVecdouble can be changed, but the order of first the inner vector matters! */
  %template(VecDouble) vector<double>;
  %template(VecVecdouble) vector< vector<double> >;
}

%include "code.h"

SWIG ব্যবহার করে, আমরা SWIG ইন্টারফেস সংজ্ঞা ফাইল থেকে একটি সি ++ ইন্টারফেস উত্স কোড উত্পন্ন করি ..

swig -c++ -python code.i

অবশেষে আমরা উত্পন্ন সি ++ ইন্টারফেস উত্স ফাইলটি সংকলন করি এবং পাইথন ("_" বিষয়গুলি) দ্বারা সরাসরি আমদানযোগ্য এমন একটি ভাগ করা লাইব্রেরি তৈরি করতে সমস্ত কিছু সংযুক্ত করি:

g++ -c -fPIC code_wrap.cxx  -I/usr/include/python2.7 -I/usr/lib/python2.7
g++ -shared -Wl,-soname,_code.so -o _code.so code.o code_wrap.o

পাইথন স্ক্রিপ্টগুলিতে আমরা এখন ফাংশনটি ব্যবহার করতে পারি:

#!/usr/bin/env python

import code
a= [[3,5,7],[8,10,12]]
print a
b = code.average(a)
print "Assignment done"
print a
print b

আসল কেস বাস্তবায়ন যেখানে সি ++ কোড স্টাইল ভেক্টরগুলিকে নন কনস্ট রেফারেন্স হিসাবে পাস করা হয় এবং তাই পাইপথন
অ্যান্টোনেলো

33

এছাড়াও রয়েছে pybind11যা বুস্ট . পাইথনের হালকা ওজনের সংস্করণের মতো এবং সমস্ত আধুনিক সি ++ কম্পাইলারের সাথে সামঞ্জস্যপূর্ণ:

https://pybind11.readthedocs.io/en/latest/


1
আজ !! 2020 এটি শীর্ষ উত্তর হওয়া উচিত! এটি একটি টেম্পলেট শিরোনাম কেবল লাইব্রেরি। অনেক বিশাল প্রাসঙ্গিক প্রকল্পগুলি এটির প্রস্তাব দেয়, যেমন Pytorch পাইটর্চ.অর্গVS Community
টিউটোরিয়ালস

30

পাইরেক্স বা সিথন পরীক্ষা করে দেখুন । সি / সি ++ এবং পাইথনের মধ্যে ইন্টারফেস করার জন্য এগুলি পাইথনের মতো ভাষা।


1
সিথনের জন্য +1! আমি সিএফআই চেষ্টা করি নি তাই আমি কোনটি ভাল তা বলতে পারি না তবে সাইথনের সাথে আমার খুব ভাল অভিজ্ঞতা হয়েছিল - আপনি এখনও পাইথন কোড লিখছেন তবে আপনি এতে সি ব্যবহার করতে পারেন। সিথনের সাথে বিল্ডিং প্রক্রিয়াটি স্থাপন করা আমার পক্ষে কিছুটা কঠিন ছিল, যা আমি পরে একটি ব্লগ পোস্টে ব্যাখ্যা করেছিলাম:
মার্টিনসোসিক

আপনি উত্তরটি আর লিংক-উত্তর হিসাবে আর উন্নত করতে চাইতে পারেন।
অ্যাডেলিন

আমি প্রায় এক সপ্তাহ ধরে সাইথন ব্যবহার করছি এবং আমি এটির অনেক পছন্দ করি: 1) আমি ব্যবহার করতে গিয়ে টাইপগুলি দেখেছি এবং এটি অনেক খারাপ এবং খুব ত্রুটিযুক্ত প্রবণতা 2) এটি আপনাকে কিছু পাইথন কোড নিতে এবং এটির গতি বাড়ানোর অনুমতি দেয় স্ট্যাটিকালি একা জিনিস টাইপ করা থেকে 3) সি / সি ++ পদ্ধতি এবং অবজেক্টের জন্য পাইথন র‍্যাপারগুলি লেখার পক্ষে সহজ কথা 4) এটি এখনও ভালভাবে সমর্থিত। এটি ভেনভেস এবং ক্রস-সংকলনগুলিতে আরও নির্দেশিকা এবং ইন্সটল করার সাথে আরও কিছু করতে পারে যা কার্যকর হতে বেশ খানিকটা সময় নিয়েছে। এখানে খুব ভাল 4 ঘন্টা ভিডিও টিউটোরিয়াল রয়েছে: youtube.com/watch?v=gMvkiQ-gOW8
ডেন-জেসন

22

আধুনিক সি ++ এর জন্য সিপ্পি ব্যবহার করুন: http://cppyy.readthedocs.io/en/latest/

এটি ক্লিংয়ের উপর ভিত্তি করে, ক্ল্যাং / এলএলভিএম এর সি ++ দোভাষী। বাইন্ডিংগুলি রান-টাইমে থাকে এবং কোনও অতিরিক্ত মধ্যবর্তী ভাষা প্রয়োজন হয় না। ঝাঁকুনির জন্য ধন্যবাদ, এটি সি ++ 17 সমর্থন করে।

পাইপ ব্যবহার করে এটি ইনস্টল করুন:

    $ pip install cppyy

ছোট প্রকল্পগুলির জন্য, আপনার আগ্রহী প্রাসঙ্গিক লাইব্রেরি এবং শিরোনামগুলি কেবল লোড করুন Eg উদাহরণস্বরূপ ctyype উদাহরণ থেকে কোড নিন এই থ্রেড, তবে শিরোনাম এবং কোড বিভাগে বিভক্ত:

    $ cat foo.h
    class Foo {
    public:
        void bar();
    };

    $ cat foo.cpp
    #include "foo.h"
    #include <iostream>

    void Foo::bar() { std::cout << "Hello" << std::endl; }

এটি সংকলন:

    $ g++ -c -fPIC foo.cpp -o foo.o
    $ g++ -shared -Wl,-soname,libfoo.so -o libfoo.so  foo.o

এবং এটি ব্যবহার করুন:

    $ python
    >>> import cppyy
    >>> cppyy.include("foo.h")
    >>> cppyy.load_library("foo")
    >>> from cppyy.gbl import Foo
    >>> f = Foo()
    >>> f.bar()
    Hello
    >>>

বড় প্রকল্পগুলি প্রস্তুত প্রতিবিম্বের তথ্য স্বয়ংক্রিয়ভাবে লোড করা এবং সেগুলি তৈরি করার জন্য কুমেক টুকরো সমর্থন করে, যাতে ইনস্টল করা প্যাকেজগুলির ব্যবহারকারীরা সহজেই চালাতে পারেন:

    $ python
    >>> import cppyy
    >>> f = cppyy.gbl.Foo()
    >>> f.bar()
    Hello
    >>>

এলএলভিএমকে ধন্যবাদ, উন্নত বৈশিষ্ট্য যেমন স্বয়ংক্রিয় টেম্পলেট ইনস্ট্যান্টেশন সম্ভব। উদাহরণটি চালিয়ে যেতে:

    >>> v = cppyy.gbl.std.vector[cppyy.gbl.Foo]()
    >>> v.push_back(f)
    >>> len(v)
    1
    >>> v[0].bar()
    Hello
    >>>

দ্রষ্টব্য: আমি সিপ্পির লেখক।


3
সত্যই এটি হয় না: পাইথনের সি সি এক্সটেনশন মডিউলগুলি লেখার জন্য সিথন একটি পাইথনের মতো প্রোগ্রামিং ল্যাঙ্গুয়েজ (সিথন কোডটি সি-এপিআই বয়লারপ্লেটের সাথে একত্রে সি অনুবাদ করা হয়)। এটি কিছু বেসিক সি ++ সমর্থন সরবরাহ করে। সিপ্পির সাথে প্রোগ্রামিংয়ে কেবল পাইথন এবং সি ++ জড়িত, কোনও ভাষা এক্সটেনশন নেই। এটি পুরোপুরি রান-টাইম এবং অফলাইন কোড জেনারেট করে না (অলস প্রজন্মের পরিমাণ আরও ভাল। এটি আধুনিক সি ++ (অন্তর্ভুক্ত স্বয়ংক্রিয় টেম্পলেট ইনস্ট্যান্টেশন, মুভস, ইনিশিয়ালার_লিস্টস, ল্যাম্বডা ইত্যাদির ইত্যাদি) লক্ষ্যবস্তু করে এবং পাইপাই স্থানীয়ভাবে সমর্থিত (যেমন ধীর সি-এপিআই এমুলেশন স্তর দ্বারা নয়)।
উইম লাভ্রিজেন

2
এই পাইএইচপিসি 16 পেপারে অনেকগুলি বেঞ্চমার্ক সংখ্যা রয়েছে। তার পর থেকে সিপিথনের পক্ষে সুনির্দিষ্ট উন্নতি হয়েছে।
উইম লাভ্রিজেন

আমি এই পদ্ধতির পছন্দ করি কারণ আপনার সাথে অতিরিক্ত ইন্টিগ্রেশন কাজ করতে হবে না swig, ctypesঅথবা boost.python। আপনার সি ++ কোড দিয়ে অজগর পেতে কোড লিখতে হবে তার পরিবর্তে ... সি ++ বের করার জন্য অজগর কঠোর পরিশ্রম করে। ধরে নিচ্ছি এটি আসলে কাজ করে।
ট্রেভর বয়েড স্মিথ

সিপিপি খুব আকর্ষণীয়! আমি দস্তাবেজগুলিতে দেখতে পাচ্ছি যে পুনরায় বিতরণ এবং প্রাক-প্যাকেজিং পরিচালনা করা হয়েছে। অজগর কোডটিও প্যাকেজ করে এমন সরঞ্জামগুলি (উদাহরণস্বরূপ, পাইআইনস্টলার) দিয়ে কি এটি ভাল কাজ করার জন্য পরিচিত? এবং এটি কি মূল প্রকল্পের সাথে সম্পর্কিত, বা এর কাজটি উপকৃত করার জন্য?
জিমবি

ধন্যবাদ! আমি পাইআইনস্টলারের সাথে পরিচিত নই, তবে "ডিকশনারি" যা প্যাকেজ আপ ফরওয়ার্ড ডিক্লেশনস, পাথ এবং শিরোনামগুলি সি ++ কোডগুলি ভাগ করে দেওয়া লিবগুলিতে সংকলিত হয়। যেহেতু সিপ্পি সি ++ কোড বাঁধতে ব্যবহৃত হয়, তাই আমি অনুমান করি যে আরও কিছু সি ++ কোড হ্যান্ডলিং করা ভাল। এবং সেই কোডটি পাইথন সি-এপিআই-র উপর নির্ভরশীল নয় (কেবলমাত্র লিব্প্প্পি মডিউলটি), যা জিনিসগুলিকে সরল করে। সিপিপি নিজেই কনডা-ফোর্জ বা পাইপি (পিপ) ​​থেকে ইনস্টল করা যায়, সুতরাং অবশ্যই এই পরিবেশগুলির যে কোনও একটি কাজ করে। হ্যাঁ, সিপিপি পাইরোট থেকে কাঁটাচামচ হিসাবে শুরু করেছিলেন, তবে এর পরে এটি এতটা উন্নত হয়েছে যে, রুট টিম পিপিআরটকে সিপির উপরে ছাড়িয়ে দিচ্ছে।
উইম লাভ্রিজসেন

20

পাইথনকে সমস্ত বিজ্ঞানীর প্রয়োজন বলে দাবি করে এই কাগজটি মূলত বলে: পাইথনের প্রথম প্রোটোটাইপ সবকিছু। তারপরে আপনার যখন কোনও অংশ গতি বাড়ানোর দরকার হবে তখন এসডব্লিউআইজি ব্যবহার করুন এবং এই অংশটি সি তে অনুবাদ করুন


15

আমি এটি ব্যবহার করি নি তবে আমি টাইপগুলি সম্পর্কে ভাল জিনিস শুনেছি । আপনি যদি এটি সি ++ দিয়ে ব্যবহার করার চেষ্টা করছেন তবে নাম ম্যাঙ্গালিংয়ের মাধ্যমে এড়াতে ভুলবেন না extern "C"মন্তব্যের জন্য ধন্যবাদ, ফ্লোরিয়ান বুশ।


13

আমি মনে করি অজগর জন্য সিএফআই একটি বিকল্প হতে পারে।

লক্ষ্যটি পাইথন থেকে সি কোড কল করা। তৃতীয় ভাষা শেখা না করে আপনি এটি করতে সক্ষম হবেন: প্রতিটি বিকল্পের জন্য তাদের নিজস্ব ভাষা (সিথন, এসডাব্লুআইজি) বা এপিআই (সিটাইপস) শিখতে হবে। সুতরাং আমরা ধরে নিতে চেষ্টা করেছিলাম যে আপনি পাইথন এবং সি জানেন এবং আপনার শেখার দরকার হওয়া অতিরিক্ত API এর বিটগুলি ন্যূনতম করুন।

http://cffi.readthedocs.org/en/release-0.7/


2
আমি মনে করি এটি কেবল সি (সি ++ নয়) কল করতে পারে, এখনও +1 (আমি সত্যই সিএফআই পছন্দ করি)।
অ্যান্ডি

8

আমি সঠিকভাবে বুঝতে পারলে পাইথন থেকে সি ফাংশনটি কীভাবে কল করা যায় তা প্রশ্ন। তারপরে সেরা বেটটি হলেন সিটিপস (পাইথনের সমস্ত রূপ জুড়ে বিটিডাব্লু পোর্টেবল)।

>>> from ctypes import *
>>> libc = cdll.msvcrt
>>> print libc.time(None)
1438069008
>>> printf = libc.printf
>>> printf("Hello, %s\n", "World!")
Hello, World!
14
>>> printf("%d bottles of beer\n", 42)
42 bottles of beer
19

বিস্তারিত গাইডের জন্য আপনি আমার ব্লগ নিবন্ধটি উল্লেখ করতে চাইতে পারেন ।


এটি লক্ষণীয় যে সিটি টাইপগুলি পোর্টেবল করার সময় আপনার কোডের জন্য একটি উইন্ডোজ নির্দিষ্ট সি লাইব্রেরি প্রয়োজন।
প্যালেক

7

অফিসিয়াল পাইথনের একটি নথিতে সি / সি ++ ব্যবহার করে পাইথন প্রসারিত করার বিশদ রয়েছে । এমনকি এসডব্লগের ব্যবহার ছাড়াই এটি বেশ সোজা এবং উইন্ডোজে পুরোপুরি ভালভাবে কাজ করে।


6

আপনি জাভা র‍্যাপারগুলি লেখার প্রত্যাশা না করে সিথন অবশ্যই যাওয়ার পথ।

আমি runcythonকমান্ড লাইন ইউটিলিটি ব্যবহার করার পরামর্শ দিচ্ছি , এটি সিথন ব্যবহারের প্রক্রিয়াটিকে অত্যন্ত সহজ করে তোলে। আপনার যদি কাঠামোগত ডেটা সি ++ এ পাস করতে হয় তবে গুগলের প্রোটোবুফ লাইব্রেরিটি একবার দেখুন, এটি খুব সুবিধাজনক।

এখানে আমি তৈরি একটি ন্যূনতম উদাহরণ যা উভয় সরঞ্জাম ব্যবহার করে:

https://github.com/nicodjimenez/python2cpp

আশা করি এটি একটি কার্যকর সূচনা পয়েন্ট হতে পারে।


5

প্রথমে আপনার বিশেষ উদ্দেশ্যটি কী তা সিদ্ধান্ত নেওয়া উচিত। পাইথন দোভাষীকে প্রসারিত এবং এম্বেড করার বিষয়ে সরকারী পাইথন ডকুমেন্টেশন উপরে উল্লিখিত ছিল, আমি বাইনারি এক্সটেনশনের একটি ভাল ওভারভিউ যুক্ত করতে পারি । ব্যবহারের কেসগুলিকে 3 টি বিভাগে ভাগ করা যায়:

  • এক্সিলার্টর মডিউলগুলি : সিপিথনে সমমানের খাঁটি পাইথন কোডের চেয়ে দ্রুত চালানো।
  • মোড়কের মডিউল : পাইথন কোডে বিদ্যমান সি ইন্টারফেসগুলি প্রকাশ করতে।
  • নিম্ন স্তরের সিস্টেম অ্যাক্সেস : সিপিথন রানটাইম, অপারেটিং সিস্টেম বা অন্তর্নিহিত হার্ডওয়্যারগুলির নিম্ন স্তরের বৈশিষ্ট্যগুলি অ্যাক্সেস করতে।

অন্যান্য আগ্রহী এবং আপনার প্রাথমিক প্রশ্নটি যেহেতু কিছুটা অস্পষ্ট ("একটি সি বা সি ++ গ্রন্থাগারের কাছে") এর জন্য কিছু বিস্তৃত দৃষ্টিভঙ্গি দেওয়ার জন্য আমার মনে হয় এই তথ্যটি আপনার কাছে আকর্ষণীয় হতে পারে। উপরের লিঙ্কটিতে আপনি বাইনারি এক্সটেনশন এবং এর বিকল্পগুলি ব্যবহার করার অসুবিধাগুলি পড়তে পারেন।

প্রস্তাবিত অন্যান্য উত্তরগুলি বাদে আপনি যদি একটি এক্সিলার মডিউল চান তবে আপনি নুম্বা চেষ্টা করতে পারেন । এটি "আমদানির সময়, রানটাইম, বা স্ট্যাটিকালি (অন্তর্ভুক্ত পাইপিসি সরঞ্জাম ব্যবহার করে) এলএলভিএম সংকলক অবকাঠামো ব্যবহার করে অনুকূলিত মেশিন কোড উত্পন্ন করে কাজ করে"।


2

আমি সিপ্পিকে ভালবাসি, সি ++ কোড দিয়ে পাইথন প্রসারিত করা খুব সহজ করে তোলে, প্রয়োজনে নাটকীয়ভাবে পারফরম্যান্স বাড়িয়ে তোলে।

এটি শক্তিশালী এবং স্পষ্টভাবে ব্যবহার করা খুব সহজ,

এখানে আপনি উদাহরণস্বরূপ যে কীভাবে আপনি একটি নমপি অ্যারে তৈরি করতে পারেন এবং এটি C ++ এ কোনও শ্রেণীর সদস্য ফাংশনে পাস করতে পারেন।

import cppyy
cppyy.add_include_path("include")
cppyy.include('mylib/Buffer.h')


s = cppyy.gbl.buffer.Buffer()
numpy_array = np.empty(32000, np.float64)
s.get_numpy_array(numpy_array.data, numpy_array.size)

সি ++ এ:

struct Buffer {
  void get_numpy_array(int beam, double *ad, int size) {
    // fill the array
  }
}

আপনি খুব সহজেই একটি সিগন মডিউল তৈরি করতে পারেন (সিএমকে দিয়ে), আপনি সি ++ কোডটি সর্বদা পুনরায় কম্পাইল করা এড়াতে পারবেন।


1

pybind11 ন্যূনতম চলমান উদাহরণ

পাইবাইন্ড 11 এর আগে https://stackoverflow.com/a/38542539/895245 তে উল্লেখ করা হয়েছিল তবে আমি এখানে একটি কার্যকর ব্যবহারের উদাহরণ এবং বাস্তবায়ন সম্পর্কে আরও কিছু আলোচনা দিতে চাই।

সর্বোপরি, আমি পাইবাইন্ড ১১-এর উচ্চ প্রস্তাব দিচ্ছি কারণ এটি ব্যবহার করা সত্যিই সহজ: আপনি কেবল একটি শিরোনাম অন্তর্ভুক্ত করেন এবং তারপরে পাইবাইন্ড 11 আপনি পাইথনের কাছে যে সি ++ শ্রেণিটি প্রকাশ করতে চান তা পরিদর্শন করতে টেমপ্লেট যাদু ব্যবহার করে এবং স্বচ্ছভাবে তা করে।

এই টেমপ্লেট যাদুটির খারাপ দিকটি এটি পাইবাইন্ড 11 ব্যবহার করে যে কোনও ফাইলের সাথে কয়েক সেকেন্ড যুক্ত করে সংকলনটি ততক্ষণে ধীর করে দেয়, উদাহরণস্বরূপ এই ইস্যুতে তদন্তটি দেখুনPyTorch সম্মত

পাইবাইন্ড 11 কতটা ভয়ঙ্কর তা অনুভব করার জন্য এখানে একটি ন্যূনতম চলমান উদাহরণ:

class_test.cpp

#include <string>

#include <pybind11/pybind11.h>

struct ClassTest {
    ClassTest(const std::string &name) : name(name) { }
    void setName(const std::string &name_) { name = name_; }
    const std::string &getName() const { return name; }
    std::string name;
};

namespace py = pybind11;

PYBIND11_PLUGIN(class_test) {
    py::module m("my_module", "pybind11 example plugin");
    py::class_<ClassTest>(m, "ClassTest")
        .def(py::init<const std::string &>())
        .def("setName", &ClassTest::setName)
        .def("getName", &ClassTest::getName)
        .def_readwrite("name", &ClassTest::name);
    return m.ptr();
}

class_test_main.py

#!/usr/bin/env python3

import class_test

my_class_test = class_test.ClassTest("abc");
print(my_class_test.getName())
my_class_test.setName("012")
print(my_class_test.getName())
assert(my_class_test.getName() == my_class_test.name)

সংকলন এবং চালান:

#!/usr/bin/env bash
set -eux
g++ `python3-config --cflags` -shared -std=c++11 -fPIC class_test.cpp \
  -o class_test`python3-config --extension-suffix` `python3-config --libs`
./class_test_main.py

এই উদাহরণটি দেখায় যে পাইবাইন্ড 11 আপনাকে অনায়াসে ClassTestসি ++ ক্লাসটি পাইথনে প্রকাশের অনুমতি দেয় ! সংকলন একটি ফাইল তৈরি করে class_test.cpython-36m-x86_64-linux-gnu.soযা class_test_main.pyস্বয়ংক্রিয়ভাবে class_testদেশি সংজ্ঞায়িত মডিউলটির সংজ্ঞা পয়েন্ট হিসাবে উঠে যায় ।

আপনি যদি পাইথন এপিআইয়ের সাহায্যে একই জিনিসটি হাতে নিয়ে চেষ্টা করার চেষ্টা করেন তবে এটি কতটা বিস্মিত হবে তার উপলব্ধি সম্ভবত ডুবে গেছে, উদাহরণস্বরূপ এটি করার উদাহরণটি দেখুন, যার প্রায় 10x কোড রয়েছে: https://github.com /cirosantilli/python-cheat/blob/4f676f62e87810582ad53b2fb426b74eae52aad5/py_from_c/pure.c উদাহরণস্বরূপ আপনি দেখতে পাচ্ছেন যে সি কোডটি কীভাবে বেদনাদায়কভাবে এবং স্পষ্টভাবে আরও সমস্ত সদস্যের সাথে পাইথন ক্লাস বিট সংজ্ঞায়িত করতে পারে, এতে আরও তথ্য রয়েছে মেটাডাটা ...)। আরো দেখুন:

পাইবাইন্ড 11 এর অনুরূপ বলে দাবি করেছে Boost.Pythonযা https://stackoverflow.com/a/145436/895245 তে উল্লিখিত ছিল তবে আরও ন্যূনতম কারণ এটি বুস্ট প্রকল্পের ভিতরে থাকা ব্লাট থেকে মুক্তি পেয়েছে:

পাইবাইন্ড 11 একটি লাইটওয়েট হেডার-কেবল লাইব্রেরি যা পাইথন এবং এর বিপরীতে সি ++ প্রকারগুলি প্রকাশ করে, মূলত বিদ্যমান সি ++ কোডের পাইথন বাইন্ডিংগুলি তৈরি করে। এর লক্ষ্যগুলি এবং বাক্য গঠনটি ডেভিড আব্রাহামসের দুর্দান্ত বুস্ট. পাইথন লাইব্রেরির সাথে সমান: কম্পাইল-টাইম ইন্ট্রোস্পেকশন ব্যবহার করে টাইপ ইনফারিংয়ের মাধ্যমে প্রথাগত এক্সটেনশন মডিউলগুলিতে বয়লারপ্লেট কোডটি ছোট করতে min

বুস্ট.পাইথন-এর মূল সমস্যা — এবং এই জাতীয় প্রকল্প তৈরির কারণ B বুস্ট। বুস্ট হ'ল ইউটিলিটি লাইব্রেরির একটি বিশাল আকারের এবং জটিল স্যুট যা প্রায় প্রতিটি সি ++ কম্পাইলারের সাথে কাজ করে। এই সামঞ্জস্যের এর দাম রয়েছে: কম্পাইলার নমুনাগুলির সর্বাধিক প্রাচীন এবং বাগিটি সমর্থন করার জন্য আরকেন টেম্পলেট ট্রিকস এবং ওয়ার্কআরাউন্ডগুলি প্রয়োজনীয়। এখন যেহেতু সি ++ 11- সামঞ্জস্যপূর্ণ সংকলকগুলি ব্যাপকভাবে উপলব্ধ, এই ভারী যন্ত্রপাতিটি অত্যধিক বৃহত এবং অপ্রয়োজনীয় নির্ভরতা হয়ে দাঁড়িয়েছে।

এই লাইব্রেরিটিকে বুস্ট.পাইথনের একটি ছোট্ট স্ব-অন্তর্ভুক্ত সংস্করণ হিসাবে ভাবেন যা সমস্ত কিছু ছিনিয়ে নিয়ে যায় যা বাধ্যতামূলক প্রজন্মের পক্ষে প্রাসঙ্গিক নয়। কোনও মন্তব্য ছাড়াই, মূল শিরোনাম ফাইলগুলিতে কেবল কোডের 4KK লাইন প্রয়োজন এবং পাইথন (2.7 বা 3.x, বা পাইপাই 2.7> = 5.7) এবং সি ++ স্ট্যান্ডার্ড লাইব্রেরির উপর নির্ভর করে। এই কমপ্যাক্ট বাস্তবায়নটি নতুন সি ++ 11 ভাষার কয়েকটি বৈশিষ্ট্য (বিশেষত: টিপলস, ল্যাম্বডা ফাংশন এবং ভেরিয়াদিক টেম্পলেট) এর জন্য ধন্যবাদ জানানো হয়েছিল। এটি তৈরির পর থেকে, এই পাঠাগারটি বুস্ট.পাইথনের বাইরেও বিভিন্ন উপায়ে বৃদ্ধি পেয়েছে, অনেকগুলি সাধারণ পরিস্থিতিতে নাটকীয়ভাবে সহজ বাঁধাই কোডের দিকে নিয়ে যায়।

পাইবাইন্ড 11 হ'ল বর্তমান মাইক্রোসফ্ট পাইথন সি বাইন্ডিং ডকুমেন্টেশন দ্বারা প্রকাশিত একমাত্র অ-নেটিভ বিকল্প: https ://docs.mic Microsoft.com/en-us/visualstudio/python/working-with-c-cpp-python-in- এ- ভিজ্যুয়াল-স্টুডিও? দেখুন = বনাম -2018 ( সংরক্ষণাগার )।

উবুন্টু 18.04, পাইবাইন্ড 11.0.1.1, পাইথন 3.6.8, জিসিসি 7.4.0 এ পরীক্ষিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.