Opening DLG box present in MFC using python - python

I am trying to open a DLG box present in MFC using python. I have tried two methods within extern C.
1st method
extern "C"
{ DLLEXPORT void open_dlg_32k_trim()
{
IDD_32KHZ_CTRL_CODE *obj=new IDD_32KHZ_CTRL_CODE;
//customer function to store first dialig object
obj->Create(IDD_32K_CONTROL,obj);
obj->ShowWindow(SW_NORMAL);
}
}
2nd method
extern "C"
{ DLLEXPORT void open_dlg_32k_trim()
{
IDD_32KHZ_CTRL_CODE ob;
ob.DoModal();
}
}
The code compiles successfully on dll side. But while calling the function from the python the code it is throwing error
enter image description here
Can you help me out where I am doing wrong and what is the first thing to look into .

Related

How Cython convert python code with some python libraries like scipy into C++ correctly?

0 My aim is to embedding some python code with scipy library into C++ code, and I want to run the C++ code without any python installation. This is my current process:
1
Saving the following code as a .pyx file:
import scipy.stats as sp
cdef public float ppf(const float c, const float a, const float s):
return sp.gamma.ppf(c, a=a, loc=0, scale=s)
2 Using "cython" to generate .c and .h file
cython XXX.pyx
3 Generating .dll file from .c and .h with Visual Studio:
extern "C"
{
__declspec(dllexport) float __stdcall _ppf(const float c, const float r, const float k)
{
return ppf(c, r, k);
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
Py_Initialize();
PyInit_ppf();
break;
case DLL_PROCESS_DETACH:
Py_Finalize();
break;
}
return TRUE;
}
4 Calling the .dll file without python installation:
int main()
{
typedef int(*pAdd)(const float c, const float r, const float k);
HINSTANCE hDLL = LoadLibrary(_T("Win32Project.dll"));
if (hDLL)
{
pAdd pFun = (pAdd)GetProcAddress(hDLL, "_ppf");
if (pFun)
{
float i = pFun(0.0000001, 5.0, 1.0);
cout << "i = " << i << endl;
}
}
system("pause");
return 0;
}
5 The code outputs a very large random value(however the correct result is fixed around 1.0). I also test a simple addition operation in step 1 without scipy dependency to verify correctness of the pipeline, and it works. But I don't know what is wrong when I use scipy library. How can I convert the python with scipy into dll correctly?
Note: I guess there should be many dependencies with scipy, so I use "pyinstaller" to generate all relative .dll files. I put these files into the Visual Studio project directory at the same level as *.exe, it still doesn't work. I don't know whether I use these files correctly, or any other reason?

Is it C++ for loop had require run time?

I had one c++ program that inside for loop, calling a function.
The function is doing a heavy process, it is embedded with python and performing image processing.
My question is, why can it only run at the first instance of the variable?
Main function (I only show the part of code require in this title):
int main(){
for(int a = 0;a<5;a++){
for(int b=0;b<5;b++){
// I want every increment it go to PyRead() function, doing image processing, and compare
if(PyRead()==1){
// some application might be occur
}
else {
}
}
}
PyRead() function, the function in c++ to go into python environment performing image processing:
bool PyRead(){
string data2;
Py_Initialize();
PyRun_SimpleString("print 'hahahahahawwwwwwwwwwwww' ");
char filename[] = "testcapture";
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");
PyObject * moduleObj = PyImport_ImportModule(filename);
if (moduleObj)
{
PyRun_SimpleString("print 'hahahahaha' ");
char functionName[] = "test";
PyObject * functionObj = PyObject_GetAttrString(moduleObj, functionName);
if (functionObj)
{
if (PyCallable_Check(functionObj))
{
PyObject * argsObject = PyTuple_New(0);
if (argsObject)
{
PyObject * resultObject = PyEval_CallObject(functionObj, argsObject);
if (resultObject)
{
if ((resultObject != Py_None)&&(PyString_Check(resultObject)))
{
data2 = PyString_AsString(resultObject);
}
Py_DECREF(resultObject);
}
else if (PyErr_Occurred()) PyErr_Print();
Py_DECREF(argsObject);
}
}
Py_DECREF(functionObj);
}
else PyErr_Clear();
Py_DECREF(moduleObj);
}
Py_Finalize();
std::cout << "The Python test function returned: " << data2<< std::endl;
cout << "Data2 \n" << data2;
if(compareID(data2) == 1)
return true;
else
return false;
}
This is second time I ask this question in stack overflow. I hope this time this question will be more clear!
I can successful compile with no error.
When I run the program, I realize at a=0, b=0 it will go to PyRead() function and return value, after that it go to a=0, b=1, at that moment the whole program will end.
It supposes to go to PyRead() function again, but it does not do that and straight ending the program.
I must strongly mention that PyRead() function needed a long time to run (30seconds).
I had no idea what happens, seeking for somehelp. Please focus on the Bold part to understand my question.
Thanks.
See the comment in https://docs.python.org/2/c-api/init.html#c.Py_Finalize
Ideally, this frees all memory allocated by the Python interpreter.
Dynamically loaded extension modules loaded by Python are not unloaded.
Some extensions may not work properly if their initialization routine is called more than once
It seems your module, does not play well with this function.
A workaround can be - create the script on the fly and call it with python subprocess.

Limit Zbar to QR code only in Python

I'm using Zbar with it's Processor option in Python. I've been trying to figure out how to limit the symbology to QR-code only, but have only found answers for C as it follows:
scanner = new ImageScanner();
scanner.setConfig(Symbol.QRCODE, Config.ENABLE, 1);
I understand that the original code is written for C but is there anyway to do it in Python? Python isn't my main language and it's a bit difficult for me to understand what the arguments are in this case for processor.parse_config() (which I have currently set to 'enable'):
From https://github.com/npinchot/zbar/blob/master/processor.c
static PyObject*
processor_parse_config (zbarProcessor *self,
PyObject *args,
PyObject *kwds)
{
const char *cfg = NULL;
static char *kwlist[] = { "config", NULL };
if(!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &cfg))
return(NULL);
if(zbar_processor_parse_config(self->zproc, cfg)) {
PyErr_Format(PyExc_ValueError, "invalid configuration setting: %s",
cfg);
return(NULL);
}
Py_RETURN_NONE;
}
I don't even understand why 'enable' is a valid argument.
Took me some time to figure this out since there's no documentation and the config format is counter-intuitive, IMO, but here you go:
proc.parse_config('disable')
proc.parse_config('qrcode.enable')
The first line, disable, disables all scanners.
The second line enables the qrcode scanner.

How can a pointer be passed between Rust and Python?

I am experimenting with writing a library in Rust that I can call from Python code. I would like to be able to pass a void pointer back to Python so that I can hold state between calls into Rust. However, I get a segfault in Rust when trying to access the pointer again.
Full code samples and crash report: https://gist.github.com/robyoung/3644f13a05c95cb1b947
The code
#![feature(libc)]
#![feature(alloc)]
extern crate libc;
use std::boxed;
pub struct Point {
x: i64,
y: i32,
}
#[no_mangle]
pub extern "C" fn start_state() -> *mut Point {
let point = Box::new(Point{x: 0, y: 10});
let raw = unsafe { boxed::into_raw(point) };
println!("{:?}", raw);
raw
}
#[no_mangle]
pub extern "C" fn continue_state(point: *mut Point) -> i32 {
println!("{:?}", point);
let p = unsafe { Box::from_raw(point) };
println!("{} {}", p.x, p.y);
0
}
import ctypes
lib = ctypes.cdll.LoadLibrary('target/libpytesttype.so')
lib.start_state.restype = ctypes.c_void_p
pointer = lib.start_state()
print("{:x}".format(pointer))
lib.continue_state(pointer)
The output
0xdc24000
10dc24000
0xdc24000
[1] 64006 segmentation fault python src/main.py
What am I doing wrong?
eryksun nailed it:
On the Python side, you're missing lib.continue_state.argtypes = (ctypes.c_void_p,). Without defining the parameter as a pointer, ctypes uses the default conversion for a Python integer, which truncates the value to 32-bit, e.g. 0x0dc24000. If you're lucky accessing that address triggers a segfault immediately.
My output (with my own padding) was:
0x103424000
103424000
0x 3424000
So the Debug formatter for pointers should be fine. Not sure why your output differs.
After adding
lib.continue_state.argtypes = (ctypes.c_void_p,)
The program ran just fine.

I want to embed Python to MVC application, by linking dynamically to python

I want to embed Python to m vc application, by linking dynamically to Python.
hModPython = AfxLoadLibrary("Python23.dll");
pFnPyRun_SimpleString *pFunction = NULL;
pFnPy_Initialize *pPy_Initialize = NULL;
pFunction = (pFnPyRun_SimpleString *)::GetProcAddress(hModPython, "PyRun_SimpleString");
pPy_Initialize = (pFnPy_Initialize *)::GetProcAddress(hModPython, "Py_Initialize");
try
{
pPy_Initialize();
if ( pFunction )
{
(*pFunction)("import sys"); // call the code
}
else
{
AfxMessageBox("unable to access function from python23.dll.", MB_ICONSTOP|MB_OK);
}
}
catch(...)
{
}
And then I want to execute a Python script through my MFC application -
HANDLE hFile = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwSize = GetFileSize(hFile, NULL);
DWORD dwRead;
char *s = new char[dwSize +1];
ReadFile(hFile, s, dwSize, &dwRead, NULL);
s[dwSize] = '\0';
CString wholefile(s);
wholefile.Remove('\r');
wholefile+="\n";
CloseHandle(hFile);
pFnPy_CompileString *pFPy_CompileString = (pFnPy_CompileString *)::GetProcAddress(hModPython, "Py_CompileString");
CString fl(file);
PyObject* pCodeObject = pFPy_CompileString(wholefile.GetBuffer(0), fl.GetBuffer(0), Py_file_input);
if (pCodeObject != NULL)
{
pFnPyEval_EvalCode *pFPyEval_EvalCode = (pFnPyEval_EvalCode *)::GetProcAddress(hModPython, "PyEval_EvalCode");
PyObject* pObject = pFPyEval_EvalCode((PyCodeObject*)pCodeObject, m_Dictionary, m_Dictionary);
}
I am facing two problems here , I want to link to Python dynamically and also make my vc application independent of the location on which Python is installed on the users machine. However , I am required to include python.h for my code to compile the following declaration.
PyObject* pCodeObject
Is there a workaround for this ? Or do I have to specify the include for "Python.h" ? Which would mean again the program becomes path dependent.
I tried copying some of the python definitions including PyObject into a header in my mfc app. Then it complies fine. but Py_CompileString call fails. so finally I am unable to run script from my MFC application by linking to python dynamically.
How can this be done ? Please help. Is there a different approach to linking to python dynamically. Please could you write to me ?
What you are doing is quite triky... I don't understand the problem with Python.h. It is needed only for compiling your program, not for running it. Surely you do not need it to be compile-time-path-independent, do you?
Anyway, you may get rid of the PyObject* definition simply by replacing it with void*, because they are binary compatible types. And it looks like you don't care too much about the type safety of your solution.
I'd say that the reason why your Py_CompileString fails may be because you have an error in your script, or something. You should really look into the raised python exception.

Categories

Resources