python embedding


Author: Dave
Date: 08.23.23 - 10:47pm



As i am required to work more with python, I am going to want to interact with it closer from native code. Shelling out to command line scripts is fine for most things honestly..but what if I just want to use a python feature from my native code. So many libraries.

I experimented with this years ago, but now I cant ignore it anymore :(


Edit: I also started experiments with VB embedding here that include interacting with vb com objects, threading, and even a basic debugger implementation

Here is something small to play with in C (note something in my blog ate the embedded new lines and back slashs)

output is:
3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:30:09) [MSC v.1934 32 bit (Intel)]
['arg1', 'arg2']
['C:Py311embedembed', 'C:Py311python311.zip', 'C:Py311DLLs', 'C:Py311Lib', 'C:Py311embedRelease', 'C:Py311', 'C:Py311Libsite-packages']
hi: test xx=64
c ret: 777
in myFunc:999
script var1=123
#define PY_SSIZE_T_CLEAN
#include 
 
#pragma warning(disable : 4996) 

static PyObject* emb_print(PyObject* self, PyObject* args){
    char* ignorestring;

    if (!PyArg_ParseTuple(args, "s", &ignorestring)) 
        return NULL; 

    printf("hi: %s
", ignorestring);

    return PyLong_FromLong(777);
}

static PyMethodDef EmbMethods[] = {
    {"print", emb_print, METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL}
};

static PyModuleDef EmbModule = {
    PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods,
    NULL, NULL, NULL, NULL
};

static PyObject* PyInit_emb(void){
    return PyModule_Create(&EmbModule);
}

int main(int argc, char* argv[]){

    wchar_t* sargv[] = { (wchar_t*)L"arg1", (wchar_t*)L"arg2", 0 };

    PyImport_AppendInittab("emb", &PyInit_emb); //add c functions to python
    //Py_SetProgramName(argv[0]);
   // Py_SetPythonHome(python_home);
    Py_Initialize();

    PySys_SetArgv(2, sargv);

    PyObject* mod = PyImport_ImportModule("__main__");
    PyModule_AddIntConstant(mod, "xx", 64); //set a global

    PyRun_SimpleString("import emb
import sys
print(sys.version); print(sys.argv);print(sys.path)
print('c ret: ' + str(emb.print('test xx='+ str(xx))))
var1=123
def myFunc(z):
    print('in myFunc:' + str(z))
");

    PyObject *pFunc = PyObject_GetAttrString(mod, "myFunc"); //call a py function
    if (pFunc && PyCallable_Check(pFunc)) {
        PyObject* pArgs = PyTuple_New(1);
        PyObject* pValue = PyLong_FromLong(999);
        PyTuple_SetItem(pArgs, 0, pValue);
        pValue = PyObject_CallObject(pFunc, pArgs);
    }

    PyObject* var1Py = PyObject_GetAttrString(mod, "var1"); //read a global
    int var1Int = PyLong_AsLong(var1Py);

    printf("script var1=%d

", var1Int);

    if (Py_FinalizeEx() < 0)  printf("finalize failed
");

    return 0;
    
}





Comments: (0)

 
Leave Comment:
Name:
Email: (not shown)
Message: (Required)
Math Question: 50 + 10 = ? followed by the letter: J 



About Me
More Blogs
Main Site
Posts: (All)
2024 ( 2 )
2023 (9)
     VB6 Virtual Files
     File handles across dlls
     python abort / script timeout
     py4vb
     VB6 Python embed w/debugger
     python embedding
     VB6 IDE Enhancements
     No Sleep
     A2W no ATL
2022 (4)
     More VB6 - C data passing
     Vb6 Asm listing
     Byte Array C to VB6
     Planet Source Code DVDs
2021 (2)
     Obscure VB
     VB6 IDE SP6
2020 ( 4 )
2019 ( 5 )
2018 ( 6 )
2017 ( 6 )
2016 ( 22 )
2015 ( 15 )
2014 ( 25 )
2013 ( 4 )
2012 ( 10 )
2011 ( 7 )
2010 ( 11 )
2009 ( 3 )