Skip to content
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

version is used as a special field, but Vips library have function named this way #238

Open
v1993 opened this issue Nov 29, 2019 · 5 comments

Comments

@v1993
Copy link
Contributor

v1993 commented Nov 29, 2019

After having some not so fun time trying to debug this issue (it somehow worked right way first time and I have no idea why), it looks like I've found a problem regarding Vips library.

lgi allows to take a look at version of package loaded using field called version: https://github.com/pavouk/lgi/blob/master/lgi/gi.c#L680-L684

However, Vips library have function named this way (copied from /usr/share/gir-1.0/Vips-8.0.gir):

    <function name="version" c:identifier="vips_version">
      <doc xml:space="preserve"
           filename="iofuncs/init.c"
           line="1076">Get the major, minor or micro library version, with @flag values 0, 1 and
2.

Get the ABI current, revision and age (as used by libtool) with @flag
values 3, 4, 5.</doc>
      <source-position filename="include/vips/vips.h" line="178"/>
      <return-value transfer-ownership="none">
        <doc xml:space="preserve"
             filename="iofuncs/init.c"
             line="1086">library version number</doc>
        <type name="gint" c:type="int"/>
      </return-value>
      <parameters>
        <parameter name="flag" transfer-ownership="none">
          <doc xml:space="preserve"
               filename="iofuncs/init.c"
               line="1078">which field of the version to get</doc>
          <type name="gint" c:type="int"/>
        </parameter>
      </parameters>
    </function>

As a result, lgi overrides this function and returns its own string instead. Commenting out that part of code makes everything work as intended.

It worked first time I tried it (version was a function) and I don't know why:
print(lgi.Vips:_resolve(true).version) still returns string value.

Are there any ways to work this around? Any ideas how it worked the first time?

I'd suggest to prefix all special names reserved by lgi with _ like you did with _resolve to avoid such collisions in the future, so it would be _version, _name, etc. If you agree with this, I can quickly submit a patch (they aren't documented anywhere, so it shouldn't be a big deal).

@v1993
Copy link
Contributor Author

v1993 commented Nov 29, 2019

A quick look suggests that there is no way to work this around as it is really the only place where g_irepository_find_by_name is called with user input.

@psychon
Copy link
Collaborator

psychon commented Nov 29, 2019

Random quick idea: Short term, a workaround similar to what lgi/override/cairo.lua could be possible (or not). This basically uses a dlsym wrapper to look up symbols. Specifically, require("lgi.core").module('cairo', 2).cairo_version is used to look up the cairo_version symbol.

@v1993
Copy link
Contributor Author

v1993 commented Nov 29, 2019

@psychon It does something:

> require("lgi.core").module('vips').vips_version
userdata: 0x7f9a8ae146f0

So… how can I call this function?

@psychon
Copy link
Collaborator

psychon commented Nov 29, 2019

The 0x7f9a8ae146f0 in your example is the raw address of the function. It does not get the function signature this way. I am not entirely sure how this works, but it might be to look at the cairo code, for example:
https://github.com/pavouk/lgi/blob/ff50e59e85fe808a3bf6783005041449ec2a6bb8/lgi/override/cairo.lua#L62-L63
All of the cairo bindings are specified in this way (explicitly giving the function signature), because cairo is not GObject-based.

From https://jcupitt.github.io/libvips/API/8.5/libvips-vips.html#vips-version and a close look at this cairo.lua file, I would guess:

local core = require("lgi.core")
local ffi = require("lgi.ffi")
vips_version = core.callable.new {
  addr = core.module('vips').vips_version
  ret = ffi.types.int, ffi.types.int
}
print(vips_version(0))

@v1993
Copy link
Contributor Author

v1993 commented Nov 29, 2019

@psychon After fixing a typo it seems to work. Thank you! Actually, it wasn't a big hurry (I have more important things to port from that library).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants