Code Monkey home page Code Monkey logo

ffpython's Introduction

ffpython

support python3 , python2

ffpython is a c++ lib,which is to simplify task that embed python and extend python. For example, call python function, register c++ function to python, register c++ class to python. Only one implement c++ header file.

Project Goals

  • easier to embed python script
  • easier to call python function
  • easier to set or get var in python script
  • easier to extend python with c++ static function
  • easier to extend python with c++ class. C++ class Once registed, python can use it like builtin type.
  • when python exception throw, ffpython will wrap it as a std exception which includes python traceback info.

Supported Python versions

  • python2.7 python3, win / linux

Embed Python script in C++

Get / Set varialbe in python script/module

    printf("sys.version=%s\n", ffpython.getVar<std::string>("sys", "version").c_str());
    ffpython.setVar("fftest", "global_var", "OhNice");
    printf("fftest.global_var=%s\n", ffpython.getVar<std::string>("fftest", "global_var").c_str());

call python function, Support all base type as arg or return value. Nine args can be supported.

	int a1 = 100; float a2 = 3.14f; std::string a3 = "OhWell";
    ffpython.call<void>("fftest", "testBase", a1, a2, a3);

call python function, Support all STL type as arg or return value. Nine args can be supported. Vector and List for tuple and list in python,map for dict in python.

	std::vector<int> a1;a1.push_back(100);a1.push_back(200);
    std::list<std::string> a2; a2.push_back("Oh");a2.push_back("Nice");
    std::vector<std::list<std::string> > a3;a3.push_back(a2);
    
    ffpython.call<bool>("fftest", "testStl", a1, a2, a3);

register c++ class, python can use it just like builtin types.

class Foo
{
public:
	Foo(int v_) :nValue(v_)
	{
		printf("%s\n", __FUNCTION__);
	}
	virtual ~Foo()
	{
		printf("%s\n", __FUNCTION__);
	}
	int getValue()  { return nValue; }
	void setValue(int v_) { nValue = v_; }
	void testStl(std::map<std::string, std::list<int> >& v_)
	{
		printf("%s\n", __FUNCTION__);
	}
	int nValue;
};

class Dumy : public Foo
{
public:
	Dumy(int v_) :Foo(v_)
	{
		printf("%s\n", __FUNCTION__);
	}
	~Dumy()
	{
		printf("%s\n", __FUNCTION__);
	}
	void dump()
	{
		printf("%s\n", __FUNCTION__);
	}
};


static Foo* objTest(Dumy* p)
{
	printf("%s\n", __FUNCTION__);
	return p;
}

Register c++ class which inherit a class having been registered.

ffpython.call<void>("fftest", "testRegisterInheritClass");

C++ object pointer can be as a arg to python, and object can be access as a instance of builtin type in python.

	Dumy tmp_foo(2013);
	std::vector<Dumy*> vt;
	vt.push_back(&tmp_foo);
    ffpython.call<void>("fftest", "testCppObjToPy", &tmp_foo);
	printf("testCppObjToPy changed nValue=%d\n", tmp_foo.nValue);
	ffpython.call<void>("fftest", "testCppObjToPy2", vt);

Extend Python

register c++ static function, all base type supported. Arg num can be nine.

static int printVal(int a1, float a2, const std::string& a3, const std::vector<double>& a4)
{
    printf("%s[%d,%g,%s,%d]\n", __FUNCTION__, a1, a2, a3.c_str(), (int)a4.size());
    return 0;
}
struct OpsTest
{
    static std::list<int> returnStl()
    {
        std::list<int> ret;ret.push_back(1024);
        printf("%s\n", __FUNCTION__);
        return ret;
    }
};


std::string testRegFunction(FFPython& ffpython)
{
    ffpython.regFunc(&printVal, "printVal")
            .regFunc(&OpsTest::returnStl, "returnStl");

	ffpython.regClass<Foo(int)>("Foo")
		.regMethod(&Foo::getValue, "getValue")
		.regMethod(&Foo::setValue, "setValue")
		.regMethod(&Foo::testStl, "testStl")
		.regField(&Foo::nValue, "nValue");

	ffpython.regClass<Dumy(int)>("Dumy", "Foo")
		.regMethod(&Dumy::dump, "dump");

	ffpython.regFunc(objTest, "objTest");
	return "cppext";
}

Python test script

def testBase(a1, a2, a3):
    print('testBase', a1, a2, a3)
    return 0

def testStl(a1, a2, a3):
    print('testStl', a1, a2, a3)
    return True

def test_returnStl():
    print('test_returnStl')
    #map<string, list<vector<int> > >
    ret = {'Oh':[[111,222], [333, 444] ] }
    return ret

def testRegFunction():
    import ffpython
    ffpython.printVal(123, 45.6 , "----789---", [3.14])
    ret = ffpython.returnStl()
    print('testRegFunction', ret)

def testRegisterBaseClass():
    import ffpython
    foo = ffpython.Foo(20130426)
    
    print("testRegisterBaseClass get_val:", foo.getValue())
    foo.setValue(778899)
    print("testRegisterBaseClass get_val:", foo.getValue(), foo.nValue)
    foo.testStl({"key": [11,22,33] })
    print('testRegisterBaseClass testRegisterBaseClass', foo)

def testRegisterInheritClass():
    import ffpython
    dumy = ffpython.Dumy(20130426)
    print("testRegisterInheritClass get_val:", dumy.getValue())
    dumy.setValue(778899)
    print("testRegisterInheritClass get_val:", dumy.getValue(), dumy.nValue)
    dumy.testStl({"key": [11,22,33] })
    dumy.dump()
    print('testRegisterInheritClass', dumy)

def testCppObjToPy_ext(foo):
    print('testCppObjToPy_ext', len(foo))
    for k in range(0, len(foo)):
        print('testCppObjToPy_ext', k, foo[k].nValue)
    
def testCppObjToPy(foo):
    import ffpython
    print("testCppObjToPy get_val:", foo.getValue())
    foo.setValue(778899)
    print("testCppObjToPy get_val:", foo.getValue(), foo.nValue)
    foo.testStl({"key": [11,22,33] })
    foo.nValue = 100
    print('testCppObjToPy testRegisterBaseClass', foo)

def testCppObjToPy2(dumyList):
    dumy = dumyList[0]
    import ffpython
    print("testCppObjToPy get_val:", dumy.getValue())
    dumy.setValue(778899)
    print("testCppObjToPy get_val:", dumy.getValue(), dumy.nValue)
    dumy.testStl({"key": [11,22,33] })
    dumy.dump()
    ffpython.objTest(dumy)
    print('testCppObjToPy', dumy)
    
    return dumy

class PyClass:
    def __init__(self):
        print('PyClass init....')
    def sayHi(self, a1, a2):
        print('sayHi..', a1, a2)
def testCppObjReturnPyObj():
    import ffpython
    return PyClass()
def testCppObjReturnPyLambda():
    def testLambda(a1):
        print('testLambda....', a1)
    return testLambda

Summary

  • ffpython Only One implement head file, it is easy to itegrate to project.
  • ffpython is simplely wrap for python api, so it is efficient.

ffpython's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ffpython's Issues

linux下编译增加gcc选项-c -O2 -Wall 编译失败

linux下编译增加gcc选项-c -O2 -Wall 编译失败,这问题有解?
In file included from /usr/include/python2.7/Python.h:80:0,
from ffpython.h:4,
from example.cpp:6:
ffpython.h: In member function ‘int ffpython_t::init_pyclass(PyObject_)’:
/usr/include/python2.7/object.h:767:22: warning: dereferencing type-punned pointer will break strict-aliasing rules -Wstrict-aliasing->ob_refcnt++)
^
ffpython.h:1274:13: note: in expansion of macro ‘Py_INCREF’
Py_INCREF(&m_all_pyclass[i].pytype_def);
^
ffpython.h: In static member function ‘static PyObject_ pytype_traits_t::pyobj_from_cppobj(bool)’:
/usr/include/python2.7/object.h:767:22: warning: dereferencing type-punned pointer will break strict-aliasing rules -Wstrict-aliasing->ob_refcnt++)
^
/usr/include/python2.7/boolobject.h:27:31: note: in expansion of macro ‘Py_INCREF’
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
^
ffpython.h:1705:13: note: in expansion of macro ‘Py_RETURN_TRUE’
Py_RETURN_TRUE;
^
/usr/include/python2.7/object.h:767:22: warning: dereferencing type-punned pointer will break strict-aliasing rules -Wstrict-aliasing->ob_refcnt++)
^
/usr/include/python2.7/boolobject.h:28:32: note: in expansion of macro ‘Py_INCREF’
#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
^
ffpython.h:1707:9: note: in expansion of macro ‘Py_RETURN_FALSE’
Py_RETURN_FALSE;
^
In file included from example.cpp:6:0:
ffpython.h: In member function ‘pyext_tool_t& pyext_tool_t::parse_arg(T&)’:
ffpython.h:2213:56: warning: typedef ‘value_t’ locally defined but not used [-Wunused-local-typedefs]
typedef typename type_ref_traits_t::value_t value_t;
^
example.cpp: In function ‘void test_cpp_obj_py_obj(ffpython_t&)’:
example.cpp:140:12: warning: variable ‘p’ set but not used [-Wunused-but-set-variable]
foo_t* p = ffpython.call<foo_t*>("fftest", "test_cpp_obj_py_obj", &tmp_foo);
^
In file included from /usr/include/python2.7/Python.h:87:0,
from ffpython.h:4,
from example.cpp:6:
ffpython.h: In instantiation of ‘static PyObject* pyclass_base_info_t::release(PyTypeObject_, PyObject_) [with T = foo_t; PyObject = object; PyTypeObject = typeobject]’:
ffpython.h:700:25: required from ‘pyclass_regigster_tool_t& ffpython_t::reg_class(const string&, std::string, std::string) [with T = foo_t; CTOR = int (
)(int); std::string = std::basic_string]’
example.cpp:106:48: required from here
/usr/include/python2.7/boolobject.h:24:46: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
#define Py_True ((PyObject *) &Py_TrueStruct)
^
/usr/include/python2.7/boolobject.h:27:51: note: in expansion of macro ‘Py_True’
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
^
ffpython.h:433:17: note: in expansion of macro ‘Py_RETURN_TRUE’
Py_RETURN_TRUE;
^
ffpython.h: In instantiation of ‘static PyObject
pyclass_base_info_t::release(PyTypeObject
, PyObject_) [with T = dumy_t; PyObject = object; PyTypeObject = typeobject]’:
ffpython.h:700:25: required from ‘pyclass_regigster_tool_t& ffpython_t::reg_class(const string&, std::string, std::string) [with T = dumy_t; CTOR = int (
)(int); std::string = std::basic_string]’
example.cpp:112:103: required from here
/usr/include/python2.7/boolobject.h:24:46: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
#define Py_True ((PyObject ) &Py_TrueStruct)
^
/usr/include/python2.7/boolobject.h:27:51: note: in expansion of macro ‘Py_True’
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
^
ffpython.h:433:17: note: in expansion of macro ‘Py_RETURN_TRUE’
Py_RETURN_TRUE;
^
In file included from example.cpp:6:0:
ffpython.h: In static member function ‘static PyObject
pyext_func_traits_t<RET (
)(ARG1, ARG2, ARG3, ARG4)>::pyfunc(PyObject
, PyObject_) [with RET = int; ARG1 = int; ARG2 = float; ARG3 = const std::basic_string&; ARG4 = const std::vector&; PyObject = object]’:
ffpython.h:2287:94: warning: ‘a2’ may be used uninitialized in this function [-Wmaybe-uninitialized]
return pytype_traits_t::pyobj_from_cppobj(f(a1.value, a2.value, a3.value, a4.value));
^
ffpython.h:2667:33: note: ‘a2’ was declared here
type_ref_traits_t a2;
^
In file included from /usr/include/string.h:640:0,
from /usr/include/python2.7/Python.h:38,
from ffpython.h:4,
from example.cpp:6:
In function ‘void* memcpy(void
, const void_, size_t)’,
inlined from ‘pyclass_regigster_tool_t& pyclass_regigster_tool_t::reg(FUNC, const string&, std::string) [with FUNC = int (foo_t::)()const; std::string = std::basic_string]’ at ffpython.h:542:9,
inlined from ‘void test_register_base_class(ffpython_t&)’ at example.cpp:107:39:
/usr/include/x86_64-linux-gnu/bits/string3.h:51:71: warning: call to void
builtin___memcpy_chk(void, const void, long unsigned int, long unsigned int) will always overflow destination buffer [enabled by default]
return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (dest));
^
In function ‘void* memcpy(void
, const void
, size_t)’,
inlined from ‘pyclass_regigster_tool_t& pyclass_regigster_tool_t::reg(FUNC, const string&, std::string) [with FUNC = void (foo_t::)(int); std::string = std::basic_string]’ at ffpython.h:542:9,
inlined from ‘void test_register_base_class(ffpython_t&)’ at example.cpp:108:39:
/usr/include/x86_64-linux-gnu/bits/string3.h:51:71: warning: call to void
builtin___memcpy_chk(void, const void, long unsigned int, long unsigned int) will always overflow destination buffer [enabled by default]
return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (dest));
^
In function ‘void* memcpy(void
, const void
, size_t)’,
inlined from ‘pyclass_regigster_tool_t& pyclass_regigster_tool_t::reg(FUNC, const string&, std::string) [with FUNC = void (foo_t::)(std::mapstd::basic_string<char, std::list >&); std::string = std::basic_string]’ at ffpython.h:542:9,
inlined from ‘void test_register_base_class(ffpython_t&)’ at example.cpp:109:37:
/usr/include/x86_64-linux-gnu/bits/string3.h:51:71: warning: call to void
builtin___memcpy_chk(void, const void, long unsigned int, long unsigned int) will always overflow destination buffer [enabled by default]
return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (dest));
^
In function ‘void* memcpy(void
, const void
, size_t)’,
inlined from ‘pyclass_regigster_tool_t& pyclass_regigster_tool_t::reg(FUNC, const string&, std::string) [with FUNC = void (dumy_t::)(); std::string = std::basic_string]’ at ffpython.h:542:9,
inlined from ‘void test_register_base_class(ffpython_t&)’ at example.cpp:113:36:
/usr/include/x86_64-linux-gnu/bits/string3.h:51:71: warning: call to void
builtin___memcpy_chk(void, const void, long unsigned int, long unsigned int) will always overflow destination buffer [enabled by default]
return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));

Calling from C++ a C++ reg function by name

How do I do this ?

        FFPython ffpython;
	
        ffpython.regClass<Foo(int)>("Foo")
		.regMethod(&Foo::getValue, "getValue")
		.regMethod(&Foo::setValue, "setValue")
		.regMethod(&Foo::testStl, "testStl")
		.regField(&Foo::nValue, "nValue");

         

Then I want to call from C++

     int rv = ffpython.call????<int>("module_name", "getValue");  
     ffpython.call????<int>("module_name", "setValue", 55);

Thank you

how to get the class handle from python class

hey , i got i issue which refer the object handle .
when i define a class in Xx.py file , let's give it a nane , like pyclass .
in python file , it is easy to call the class initial funciton to creat a object , and then call the class method . for example :
obj=pyclass()
obj.sayhi() // pyclass method
in the c++ files , what i could do is to call class initiation funciton like
ffpython_t ffpython;
ffpython.call("XX", "pyclass"); // run the pyclass initiation funciton , without class instance handle

but without the class definition , i could not get the class instance handle to call the class method ,
the only method to solve such a issue is to define a class in c++ , and register it into the python class which wil inherent the pyclass , then to call the class relative method . but it's really headache . could you give any better solution ?
email: [email protected]

内存泄漏

系统:window7 64位
python:2.7.9 64位
第1592行
PyObject *pArgs = PyTuple_New(pyclass_base_info_t::pytype_info.total_args_num+1);
未被释放,会引起内存泄漏.
1

ffpython::add_path() file path changed support

issue have been solve . it belong to my python file which could not load files

hi fanchy
ffpython add specified file path by use add_path() or run_string to do this work .
after view the source code : the mechanism to load module in python is :

char buff[1024];
        SAFE_SPRINTF(buff, sizeof(buff), "import sys\nif '%s' not in 
sys.path:\n\tsys.path.append('%s')\n", path_.c_str(), path_.c_str());
        PyRun_SimpleString(buff);

but in the mixed programming , python files maybe located in several directory . once i use the add-path () , it seems the library didnot support to change the specified file path any more .
like following code :

{   ffpython_t  I_pythoner;
    ffpython_t::add_path("./py_file/");
    i_pythoner.call<void>("test_module", "sayhi");      
   # ffpython_t::add_path("./child_dir/");                     
    #i_pythoner.call<void>("test_module2", "sayhi");       # could not  find the module 
}

current directory
----py_file
--------test_module.py
--------child_dir
------------test_module.py

question

could ffpython support multiple - paths module loading ? if it could , what do i supposed to do ?

can't compiled with vs2008/vs2010/gcc

1>c:\ffpython-master\ffpython.h(37): error C2899: typename cannot be used outside a template declaration
1>c:\ffpython-master\ffpython.h(37): error C2065: 'T' : undeclared identifier
1>c:\ffpython-master\ffpython.h(37): error C2955: 'type_ref_traits_t' : use of class template requires template argument list
1> c:\ffpython-master\ffpython.h(32) : see declaration of 'type_ref_traits_t'
1>c:\ffpython-master\ffpython.h(37): error C2027: use of undefined type 'type_ref_traits_t'
1> c:\ffpython-master\ffpython.h(32) : see declaration of 'type_ref_traits_t'
1>c:\ffpython-master\ffpython.h(37): error C2146: syntax error : missing ';' before identifier 'value_t'

error C2899: typename cannot be used outside a template declaration
error C2955: 'type_ref_traits_t' : use of class template requires template argument list

here are two typical error from the logs.

under cygwin, i use gcc compile example.cpp also got errors
$ gcc example.cpp -I /usr/include/python2.7/
In file included from example.cpp:7:0:
ffpython.h:38:37: 错误:‘T’在此作用域中尚未声明
typedef typename type_ref_traits_t::value_t value_t;
^
ffpython.h:38:38: 错误:模板第 1 个参数无效
typedef typename type_ref_traits_t::value_t value_t;
^
In file included from example.cpp:7:0:
ffpython.h:1083:26: 错误:‘pyoption_t’不是一个模板
struct pyoption_traits_t<pyoption_t >
^
ffpython.h:1083:8: 错误:部分特例化中未用到模板参数:
struct pyoption_traits_t<pyoption_t >
^
ffpython.h:1083:8: 错误: ‘T’
ffpython.h:1318:24: 错误:‘pyoption_t’不是一个模板
struct pytype_traits_t<pyoption_t >
^
ffpython.h:1318:8: 错误:部分特例化中未用到模板参数:
struct pytype_traits_t<pyoption_t >
^
ffpython.h:1318:8: 错误: ‘T’

NameError: name 'ffpython' is not defined

Thank you for the code. I got the following error when trying to embed python script in C++.

Traceback (most recent call last):
File "", line 1, in
SystemError: nameless module
Traceback (most recent call last):
File "", line 8, in
NameError: name 'ffpython' is not defined
Traceback (most recent call last):
File "", line 11, in
NameError: name 'ffpython' is not defined
Traceback (most recent call last):
File "", line 10, in
NameError: name 'ffpython' is not defined
Traceback (most recent call last):
File "", line 6, in
NameError: name 'ffpython' is not defined
sys.version=
ValueError: Empty module name

Here is the code Im running

std::shared_ptr<ff::FFPython> _ffpython;
_ffpython = std::make_shared<ff::FFPython>();
printf("sys.version=%s\n", _ffpython->getVar<std::string>("sys", "version").c_str());

This run fine in python2.7, however, the error appeared when I switched to python3.5

MFC引用不能多次include

我在MFC中使用,把#include "ffpython.h"放在stdafx.h下编译不通过
使用代码

    Py_IsInitialized();
    std::string szArticleContent = CStringA(m_csArticleContent).GetString();
    ffpython_t ff;
    ff.call<void>("CSTBlogPost", "writeArticleContent", szArticleContent);
    Py_Finalize();

错误代码如下

1>stdafx.obj : error LNK2005: "public: static int __cdecl pyops_t::traceback(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?traceback@pyops_t@@SAHAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) 已经在 CSTBlogPost.obj 中定义
1>stdafx.obj : error LNK2005: "public: static int __cdecl pycall_t::call_func(struct _object *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,struct pycall_arg_t &,class pytype_tool_t &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?call_func@pycall_t@@SAHPAU_object@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@1AAUpycall_arg_t@@AAVpytype_tool_t@@AAV34@@Z) 已经在 CSTBlogPost.obj 中定义
1>D:\SystemFolder\Documents\Visual Studio 2008\Projects\CST-BlogPush\Release\CSTBlogPost.exe : fatal error LNK1169: 找到一个或多个多重定义的符号

windows上面 python27 编译后第 invalid type 错误

g++ -o app_py27 example.cpp -I"C:/Python27/include" -L"C:/Python27/libs" -lpython27

编译成功

运行./app_py27.exe

第一个函数test_base 测试中
ffpython.set_global_var("fftest", "global_var", "OhNice"); 运行正确

printf("fftest.global_var=%s\n", ffpython.get_global_var("fftest", "global_var").c_str()); 运行异常 【type invalid】

其中在fftest.py的第一个函数中增加

global global_var
print global_var, type(global_var)

测试结果global_var为 long型

请问这个是什么问题?

string format issue

i guess fanchy should be a chinese developer . chinese would not be a issue to read . so i would like to use chinese to feedback some issue about the ffpython

1 ffpython使用的是 STL::string 类作为参数传输, ffptyon 本身是作为配适器的方式嵌入到 C++ 代码中, 单纯以string 的方式传参, 对于宽字符的处理存在极大的不便, 尤其是以VS MFC 默认使用宽字符的方式, 涉及到字符类型的转换, 岂止headache 了得。
建议: ffpython 是否应该考虑支持 wstring , 例如自定义 tstring
根据系统环境, 再自动选择 是string, 还是wstring。 以此提供更好的 对非 ansi 码支持

Is there a posibility to return a custom type to python

Hi,
Great job, easy integration. Thank you.

What work around I have to make to return an object instance from a C++
function to python ?

class A{
public:
        A(){}
        ~A(){}
        void method(){ printf("%s\n",__FUNCTION__)};
};

A a;
/*
 ...
*/
A& Another::returnA(){
    return a;
}

/*
 ...
*/
e.regClass<Another()>("Another")..regMethod(&Another::returnA,"returnA");
e.regClass<A()>("A")..regMethod(&A::method,"method");

PY, something like

another = ffpython.Another()
theA = another.returnA()
theA.method()

Yields errors as:

ffpython/ffpython.h: In instantiation of ‘PyObject* ff::ScriptMethodImpl<RET (CLASS_TYPE::*)()>::handleRun() [with CLASS_TYPE = AeProcess; RET = AeDriver&; PyObject = _object]’:
ffpython/ffpython.h:1390:23:   required from here
fpython/ffpython.h:1392:48: error: incomplete type ‘ff::ScriptCppOps<A&>’ used in nested name specifier
 1392 |         return ScriptCppOps<RET>::scriptFromCpp(((CLASS_TYPE*)pobjArg->*func)());
      |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~









several issues about the ffpython

as a flesh programmer , it is not easy to use ffpython well according my experience .
1 the way to call python function in C++ environment is not safe ,
for example
in pytest. py module , there is a function
def py_mytest(var):
print "hello , this is my first test" , var
in C++ .cpp module
ffpython.call("pytest", "py_mytest","good luck"):

it's impossible for the IDE to detect the error ,or give any warming , once time i enter the incorrect module name , or function name ("pytest", "py_mytest") . the software will directly crash . it is really dangerous . the first time , i had cost lots of time to debug the error .
advice : will there any mechanism to give some warming or throw the exception once time , the module name , function name , class name , got wrong ??

2 ffpython for embeding python into c++ solution only support released version
as a test , only support released version would be ok . but at work , i really have no confidence to take this solution to embed python in my program . i had tried to find the python27_d.lib and python27_d.dll to solve this issue .. it did cost lots of time and energy . what we pursue is to make programing more simple and efficient , are not we .
thanks for your hard work .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.