enthought / comtypes

A pure Python, lightweight COM client and server framework, based on the ctypes Python FFI package.
Other
282 stars 96 forks source link

[Support] Get OSError: exception: access violation #521

Closed moi15moi closed 3 months ago

moi15moi commented 4 months ago

I am pretty sure it is a skill issue and comtypes may have nothing to do with my problem, but I can't find why I always get the exception OSError: exception: access violation writing 0x00007FFD2B0D4493 when I run this code. Link dead, use code.zip

Traceback (most recent call last):
  File "file.py", line 182, in <module>
    test()
  File "file.py", line 174, in test
    font_set.GetMatchingFonts1(
OSError: exception: access violation writing 0x00007FFF33574493

Could someones help me understand why it happen? Do I assign the wrong type in my IDWriteFontSet class?

junkmd commented 4 months ago

Please include the traceback output when an error occurs. Knowing which line the error occurred on is important for the community to assist with bug resolution.

In COM object method definitions, it is necessary to specify the Vtbl layout.

https://devblogs.microsoft.com/oldnewthing/20040205-00/?p=40733

The order of method definitions is crucial, I believe.

moi15moi commented 4 months ago

Please include the traceback output when an error occurs.

I edited my first message.

The order of method definitions is crucial, I believe.

Yes, it is. I respected the order defined by the header.

junkmd commented 4 months ago

IDWriteFontSet.GetPropertyValues is duplicated in three places. Not implementing this section may be causing inconsistencies in the vtbl index.

moi15moi commented 4 months ago

There are multiple place here where i don't specify the parameters here it and it works: https://github.com/moi15moi/FindSystemFontsFilename/blob/main/find_system_fonts_filename/windows_fonts.py

I think the issue is something else.

junkmd commented 4 months ago

While reading the IDWriteFontSet documentation, I noticed that GetPropertyValues and GetMatchingFonts are declared as overloaded methods.

Furthermore, regarding the relationship between overloaded methods and COM visible interfaces, Microsoft's documentation mentions the following.

https://learn.microsoft.com/en-us/visualstudio/code-quality/ca1402?view=vs-2019&tabs=csharp

When overloaded methods are exposed to COM clients, only the first method overload retains its name. Subsequent overloads are uniquely renamed by appending to the name an underscore character '_' and an integer that corresponds to the order of declaration of the overload.

I'm not sure how much of that description is also common to Python and comtypes. However, I think trying out the following code changes is a low-cost way.

IDWriteFontSet._methods_ = [
    STDMETHOD(wintypes.UINT, "GetFontCount"),
    STDMETHOD(HRESULT, "GetFontFaceReference", [wintypes.UINT, POINTER(POINTER(IDWriteFontFaceReference))]),
    STDMETHOD(None, "FindFontFaceReference"),  # Need to be implemented
    STDMETHOD(None, "FindFontFace"),  # Need to be implemented
    STDMETHOD(None, "GetPropertyValues"),  # Need to be implemented
-   STDMETHOD(None, "GetPropertyValues"),  # Need to be implemented
+   STDMETHOD(None, "GetPropertyValues_2"),  # Need to be implemented
-   STDMETHOD(None, "GetPropertyValues"),  # Need to be implemented
+   STDMETHOD(None, "GetPropertyValues_3"),  # Need to be implemented
    STDMETHOD(None, "GetPropertyOccurrenceCount"),  # Need to be implemented
-   STDMETHOD(HRESULT, "GetMatchingFonts1", [POINTER(DWRITE_FONT_PROPERTY), wintypes.UINT, POINTER(POINTER(IDWriteFontSet))]),
+   STDMETHOD(HRESULT, "GetMatchingFonts", [POINTER(DWRITE_FONT_PROPERTY), wintypes.UINT, POINTER(POINTER(IDWriteFontSet))]),
-   STDMETHOD(HRESULT, "GetMatchingFonts2", [POINTER(wintypes.WCHAR), wintypes.UINT, wintypes.UINT, wintypes.UINT, POINTER(POINTER(IDWriteFontSet))]),
+   STDMETHOD(HRESULT, "GetMatchingFonts_2", [POINTER(wintypes.WCHAR), wintypes.UINT, wintypes.UINT, wintypes.UINT, POINTER(POINTER(IDWriteFontSet))]),
]
junkmd commented 3 months ago

Is there an update on this issue?

moi15moi commented 3 months ago

No. It still haven't found a solution.

junkmd commented 3 months ago

Does it mean that https://github.com/enthought/comtypes/issues/521#issuecomment-2002002584 did not provide a solution to the problem?

Even if it errors out, have you noticed any differences in the error message or error type compared to before?

moi15moi commented 3 months ago

No, it changes nothing. It give me the same error. It doesn't surprise me. You can basically name the function like you want. I could rename GetFontCount to like example and call the method example and it would work.

junkmd commented 3 months ago

Is there an update on this issue?

Do you have any idea how to use IDWriteFontSet with languages other than Python or packages other than comtypes? If those work as expected in your environment, I think it's worth investigating their implementation.

moi15moi commented 3 months ago

Is there an update on this issue?

No.

Do you have any idea how to use IDWriteFontSet with languages other than Python or packages other than comtypes?

libass use it, but it is a pure C implementation, so it is a little bit different, but it gives you an idea. It declare the interface here. It call IDWriteFontSet::GetMatchingFonts here.

moi15moi commented 3 months ago

I found the issue, like I said, it was a skill issue. Here is the new code: LM5Q.zip

I needed to switch the 2 GetMatchingFonts method in IDWriteFontSet. The new order doesn't follows the header file, so I don't know why I needed to do that.

junkmd commented 3 months ago

I’m glad to hear that the issue seems to be resolved.

The header file you were referring to hasn’t been updated for 9 years. Probably, this difference in the vtable order is a discrepancy between the current and past specifications, which is inherent in software development.

Also, for the first time, I considered how to implement the overloading of COM methods in comtypes.

Your report will likely serve as a reference to help the community when a similar situation arises.

Thank you.