mono / CppSharp

Tools and libraries to glue C/C++ APIs to high-level languages
MIT License
3.13k stars 516 forks source link

Trying to make QtGui work / base method search crashes on certain occasions #328

Closed golddranks closed 10 years ago

golddranks commented 10 years ago

Hi, I'm trying to make QtSharp work. The base library, QtCore already works, but when generating wrappers to a dependent library, QtGui, it crashes. (Ref. my discussion with the QtSharp maintainer: https://github.com/ddobrev/QtSharp/issues/8 )

The problem seems to be that CppSharp doesn't handle inter-library dependencies well enough yet. As QtGui is dependent on QtCore, the wrapper generation fails.

I've been trying to debug the problems, and I recently encountered the following:

On FixDefaultParamValuesOfOverridesPass, it crashes when Class.GetRootBaseMethod(method) returns null. It tries to find a base method for a method declared in QtGui, but the base method is in QtCore. It almost finds the method, but it deems the return type of the found method to be incompatible, because the class Template of the return type of the derived method doesn't equal to the Template of the return type of the base method. It checks the Template equality using .Equals().

Clearly there exists two instances of the same underlying Template although there should (should there?) be only one.

I'm trying to fix this bug, but if you have any comments what to take into account, please tell me.

tritao commented 10 years ago

Thanks for reporting, I'll try to reproduce this later today.

golddranks commented 10 years ago

Some progress:

The type it didn't equal when it should have, was QMap, but after investigating, templates of QMap are being introduced all over the headers of QtCore, like this: template <class Key, class T> class QMap; It turns out that the QMap types that didn't equal to each other were declared in different translation units.

I'm not sure what to do about this.

golddranks commented 10 years ago

As C++ allows for multiple declarations of same thing, but only one definition, we shouldn't maybe test equality between the different template declarations using just ReferenceEquals. I implemented Equals() for Template class that checked whether their QualifiedName equals. That makes the GetRootBaseMethod() return the correct method.

Someone who knows more about the internals of CppSharp, is testing the QualifiedName adequate and enough to prove that the templates are the same?

golddranks commented 10 years ago

I'll make a pull request after getting these fixes together, but meanwhile:

It now crashes on the last pass of TranslationUnitPasses: GetterSetterToPropertyAdvancedPass.

There is a getter and setter surfaceType() and setSurfaceType() in the QWindow class of QtGui. QWindow class is derived from the QSurface class and the aforementioned getter and setter is defined there, but overridden by QWindow.

Apparently the GetterSetterToPropertyAdvancedPass is trying to convert them to a C# property. On GenerateProperty(), GetRootBaseProperty() returns a null, although it probably is meant to return the base property from QSurface class - but it doesn't exist!

Trying to fix this too.

tritao commented 10 years ago

Glad you're managing to figure out some of these issues.

My development environment is currently giving me all sorts of weird problems including crashing when compiling the solution so I'm afraid I can't help out until I sort these out.

But if you have any questions I'm here to help. About GetterSetterToPropertyAdvancedPass it would be better to ask @ddobrev as he is the original author of that pass and I'm not sure how it works.

ddobrev commented 10 years ago

@golddranks I'll try debugging the issue with GetterSetterToPropertyAdvancedPass as soon as possible.

golddranks commented 10 years ago

Allright, I think I settled it. The GetterSetterToProperty pass must process the base classes before it processes the derived classes - otherwise it will crash since it tries to access the not-yet-created properties of the base classes if they are marked as overridden. Check the newest commit in my bug fixing fork: https://github.com/golddranks/CppSharp

I'll continue with crushing the bugs.

ddobrev commented 10 years ago

Excellent! Thank you for squashing this one as well. However, I'd like to discuss your fix with Joao a little because as far as I know, base classes should've already been parsed. You see, Clang follows included headers before parsing the header itself.

ddobrev commented 10 years ago

@golddranks could you try disabling your fix and then going to QtSharp.Preprocess, replacing:

unit.ExplicityIgnored = true;

with:

unit.GenerationKind = GenerationKind.Link;

and then running the generator again.

golddranks commented 10 years ago

@ddobrev I gave it a go, but unfortunately that didn't help. When the properties in QWindow are going to be processed, QSurface has only two properties: m_type and __Instance.

ddobrev commented 10 years ago

@golddranks would you like to exchange some contacts? You can use my e-mail which you can get from the commit messages.

golddranks commented 10 years ago

Sent you email about fixing the GetterSetterToPropertyAdvancedPass in a better way.

golddranks commented 10 years ago

Hi, I'm trying to make a pull request for this commit: https://github.com/golddranks/CppSharp/commit/7a4f7eb81e82ffb65ac8bb998192b921c4c83749 but for some reason, GitHub doesn't want to show this repository as the base fork. Could you pull and merge that commit manually? It should merge cleanly to the current origin/master.

ddobrev commented 10 years ago

@golddranks you should be able to check the latest CppSharp out and then cherry-pick your commit. Anyway, since I am not the CppSharp maintainer but rather @tritao is, please take this discussion with him. You'd have to do it either way because he'd want to review it.

tritao commented 10 years ago

I'm not sure why it's not showing up as a fork. Maybe you could try re-forking the repository?