Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi
I have a application written in c++ (MFC). I have included python.h and specified the lib file. With this I am able to use functions from python c api and execute python scripts.

This requires me to include python.h and specify python23.lib to the linker. Everything works fine.

What I am trying now is , to remove the static linking to python and use LoadLibrary function to load the python dll.

I have written the following code -

typedef void (pFnPyRun_SimpleString)(char *);
typedef void (pFnPy_Initialize)();


in a function the following code -

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(...)
{
				
}


This code works fine too. I have loaded the python dll dynamically and called the functions from python c api by obtaining the function pointers using GetProcAddress.

So far good. The problem arises when i want to create a dictionary object mdict in my c++ code so that i can pass it to a

PyEval_EvalCode

PyObject* pCodeObject = 

Py_CompileString(wholefile.GetBuffer(0),path.GetBuffer(0),Py_file_input);
				
if(pCodeObject != NULL)
    PyObject* pObject = PyEval_EvalCode((PyCodeObject*)pCodeObject,mDict,mDict);


To be able to compile this i need to include python.h and link to python23.lib statically as PyObject cannot be found. Static linking was what i was trying to avoid. And therefore used loadlibrary.

How can this be handled.

Thanks in advance.
Sober
Posted
Updated 7-Jun-11 5:30am
v2
Comments
HimanshuJoshi 7-Jun-11 11:30am    
Edited to add code block.
Sergey Alexandrovich Kryukov 7-Jun-11 12:57pm    
You explain almost everything, not the very problem. Yes, you need to get each and every Python function through GetProcAddress. It's tedious, but you have all your include file where you can get all signatures, right? Why you successfully did it to some functions but don't know how to do it to others?
--SA

I don't understand why suffering so much? I would understand if you need to create something like optional or plug-in Python module in C++ code which can be unloadable. What you're trying to do looks too tedious though.

If this is your goal, I would offer the alternative approach:

Create a C++ DLL which links your Python DLL statically as you did it before. Wrap all the Python API in C++ classes, preferably in one single C++ class. Declare this class in some header file and implement in the DLL using Python API you linked. Create a single function which serves as a class factory for your wrapper class (classes). Export this function.

In you C++ code using Python API, use LoadLibrary and GetProcAddress, include the same header file where you wrapper is declared, load your wrapper DLL, load your wrapper's class factory function and use the instance of the wrapper in your code.

—SA
 
Share this answer
 
Comments
Espen Harlinn 7-Jun-11 18:59pm    
Good point, my 5
Sergey Alexandrovich Kryukov 7-Jun-11 21:45pm    
Thank you, Espen.
--SA
Mobile.Instinct 9-Sep-11 7:59am    
Hello, I seem you exactly would know what I am trying to do as well. I want to access a function in an MFC dll using Python which is very much similar to what the above question says. I have been trying lots since 4 days but no luck till now. I am new to PythonWin but have been doing MFC for about 2 months now. Could you suggest me a sample Python code for this code so that I can try it out and use it in my application?

http://www.functionx.com/visualc/libraries/staticdll.htm
This might be of interest:
http://www.boost.org/doc/libs/1_46_1/libs/python/doc/[^]

You can specify DLLs to delay load with the /delayload:python23.dll linker option. If you do not plan to use your own version of a helper function, you must also link your program with Delayimp.lib.

Best regards
Espen Harlinn
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 8-Jun-11 13:16pm    
Well, I guess this is a different Python-C++ binding. 5 for the alternative.
--SA
Espen Harlinn 8-Jun-11 14:42pm    
Yup, and it's quite easy to use - I guess he wants dynamic binding to the dll because he wants to be able execute his program - even if python isn't installed on the target computer. Thanks for the vote SAKryukov :)
Sergey Alexandrovich Kryukov 8-Jun-11 18:18pm    
Good to know. Now I know who could help on this topic. :-)
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900