-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OSError: exception: access violation writing 0x00000000 #19
Comments
i am finding this tricky to catch as the errors don't appear in my console - they just terminate the process. |
Were you able to solve this problem? I am having trouble as well... |
Maybe it you changed the volume too fast and COM cant handle it (just a guess...). A delay could help. |
I don't think I did, sorry :-( |
I was able to solve it! It was a pain to find out what did not work, but I figured it out. The problem is deeply hidden in the comtypes package which is imported when you want so set the master volume. Find the init.py of the comtypes package and search for "release". Eventually you will find the delete function of some compointer. I don't exaclty know what is going on, but by default this method should look something like this:
For me, there seemed to be a problem considering pointers of the class "<class 'comtypes.POINTER(IUnknown)'>", so I replaced this del method by the following:
I simply test if the type of my object is of the type "<class 'comtypes.POINTER(IUnknown)'>" and if that's the case, I simply don't call self.Release(). You could replace this method completely and simply use a pass statement, but this led to huge RAM consumption, so I added the little bit where it only passes on releasing the pointer if it is of the "forbidden" type. This worked brilliantly and because only very few pointers are actually of this type, only a few pointers are not deleted, so the RAM consumption is as low as before. This is especially not a problem, because beforehand, the pointers could not be deleted anyway, hence the error we all had to deal with. |
I was also running into this. As far as I can tell it is a double-free caused by using ctypes When you do this, Python has two objects referencing the COM object, but the COM object still only records a reference count of 1 because it doesn't know about the cast. The double free occurs if python deletes one of its objects, calling This can be reproduced reliably by updating if __name__ == "__main__":
- main()
+ for i in range(100):
+ main() Causing:
We can trigger the same problem by copying the interface. Anything that results in multiple python objects referencing a COM object with a reference count of 1 is bad news: def main():
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
interface2 = copy.deepcopy(interface)
if __name__ == "__main__":
for i in range(100):
main() The COM documentation - https://learn.microsoft.com/en-us/windows/win32/com/rules-for-managing-reference-counts - explains pretty well why this causes problems. The solution is to replace
with
I'll make a PR to do this in all the examples. |
When attempting to change the master volume repeatedly, sometimes get one of two [errors] as sen below:
(
The text was updated successfully, but these errors were encountered: