[C++-sig] Re: Is this use of Boost.Python safe?
David Abrahams
dave at boost-consulting.com
Thu Sep 11 16:11:33 CEST 2003
Matthew Bray <mat at matbray.com> writes:
> David Abrahams wrote:
>> Matthew Bray <mat at matbray.com> writes:
>> [snip]
>> You can do that. I'd be inclined to stick the ObjectModel code in a
>> separate DLL that's used by the App and the extension module, but
>> your way works.
>>
>
> I think this is a source of our confusion, I hope to expand on it a
> little better below (i.e. this is what I hope to do).
>
>>
>>>With this setup, it is now possible to create an instance of
>>>ObjectModel within the python interpretter and use
>>>extract<ObjectModel*>(...) in order to get access to it within the
>>>application, no doubt it is also possible to create the ObjectModel
>>>within the application and pass it to the python interpretter to use
>>> it there.
>> Yes.
>>
>>>Now my question basically regards pitfalls in this approach, there
>>> are two instances of the Python Module in use here
>> Huh!?
>> What do you mean by "two instances"?
>>
>
> The class "ObjectModel" is within the dll "my_module.pyd",
You mean that it's declared __declspec(dll[ex|im]port) and its member
function implementations are located there, I assume.
> the python interpretter has one instance of it
When you say one instance, I presume you do *not* mean what you get by
constructing or new'ing ObjectModel in C++.
> , i.e. through "import my_module", the application has another
> instance of it (the one which the application is dynamically linked
> against).
my_module.pyd is the same file in both cases?
> Hence two instances of the same dll are running concurrently.
Are you sure that has any significance? For example, are static
initializers run once or twice? Are there one or two copies of the
static data (globals) from my_module.pyd in the program? It's easy
enough to find out; just embed the following in your module:
int x = 42;
int __declspec(dllexport) getset(int y) { int z = x; x= y; return z; }
...
def("getset", getset);
and then call getset(7) from C++, start your interpreter, and invoke
print getset(0)
from Python. If the result is 7, as I expect, there's only one
instance of my_module
> We are passing objects created within python (from the
> first dll instance) into our application. When a method is called
> upon this ObjectModel instance within the application then a call is
> made to code in our second dll instance (the one the application is
> linked against). Hopefully this explains the issue a little better.
>
> +------------------------+ +---------------+ +-------------+
> | App +----------+ | | my_module.pyd |--->| Class |
> | +----| Dll stub |<-----------+---------------+ | ObjectModel |
> | v +----------+ | Dynamically Linked +-------------+
> | ObjectModel instance |
> | ^ |
> | +--|----------------+ | +---------------+ +-------------+
> | | Py Interpretter <-------------| my_module.pyd |--->| Class |
> | +-------------------+ | +---------------+ | ObjectModel |
> +------------------------+ Imported +-------------+
If there are really two instances of the DLL, and you're not
currently having any trouble, it's purely because of implementation
details of your compiler and I certainly can't say "what you're doing
is safe".
>>>but I'm sure that as long as care is taken to ensure the ObjectModel
>>>is destructed on the same heap that it was created on then there
>>> shall be no problems.
>> I wouldn't count on it. Please elaborate on what you mean by the
>> above "two instances" remark.
>>
>>>Is there any other, possibly better way to do
>>>this perhaps - e.g. without requiring the use of the module at all,
>>>simply passing the Boost.Python class descriptions directly to the
>>> embedded interpretter.
>> See http://www.boost.org/libs/python/test/embedding.cpp. Does that
>> help?
>>
>
> yes alot, thanks.
>
>> [snip]
>>>
>>> Py_Finalize();
>> ^^^^^^^^^^^
>> This is a pitfall. Boost.Python hasn't been made "finalize-safe",
>> yet. Dirk Gerritts was working on it, but...
>>
>
> Does this mean that handles aren't invalidated automatically,
> constructors arent called, memory isnt freed? Is there documentation
> on that I can find on this.
See
http://www.boost-consulting.com/boost/libs/python/todo.html#pyfinalize-safety
HTH,
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list