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

Error: type mismatch: got 'seq[string]' for 'getDatas()' but expected 'SeqString = ref SeqString:ObjectType'` #36

Closed
enthus1ast opened this issue Feb 5, 2022 · 11 comments

Comments

@enthus1ast
Copy link

enthus1ast commented Feb 5, 2022

If seq[string] is returned by a proc,
genny emits invalid code.

import genny

proc getDatas*(): seq[string] =
  result = @["a", "b", "c"]

exportSeq seq[string]:
  discard

exportProcs:
  getDatas

writeFiles("bindings", "ttt")
include bindings/internal

from generated internal.nim:

proc ttt_get_datas*(): SeqString {.raises: [], cdecl, exportc, dynlib.} =
  getDatas()

C:\Users\david\projects\gennyt\bindings\internal.nim(32, 11) Error: type mismatch: got 'seq[string]' for 'getDatas()' but expected 'SeqString = ref SeqString:ObjectType'

what works for me if i manual patch internal.nim

proc ttt_get_datas*(): SeqString {.raises: [], cdecl, exportc, dynlib.} =
  result = SeqString()
  result.s = getDatas()

Edit: Fixed import, removed nimja

@guzba
Copy link
Collaborator

guzba commented Feb 5, 2022

Thanks for the report. I've confirmed the issue and am working on this.

@treeform
Copy link
Owner

treeform commented Feb 6, 2022

Thank you for your issue! I think we have fixed it. Please pull head and try it again.

Feel free to reopen if you still have issues.

@treeform treeform closed this as completed Feb 6, 2022
@enthus1ast
Copy link
Author

yes it compiles now, thank you!

I unfortunately still cannot use it. It excepts on field access.

I compile the above testfile with:

PS C:\Users\david\projects\gennyt> nim c --app:lib -d:release --gc:orc .\ttt.nim

Then load it in ipython:

In [2]: import ttt

In [3]: d = ttt.get_datas()

In [4]: len(d)
Out[4]: 3

In [5]: print(d[0])
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
Input In [5], in <module>
----> 1 print(d[0])

File ~\projects\gennyt\bindings\ttt.py:35, in SeqString.__getitem__(self, index)
     34 def __getitem__(self, index):
---> 35     return dll.ttt_seq_string_get(self, index)

OSError: exception: access violation reading 0x0000000000000000

Nim version:

Nim Compiler Version 1.6.0 [Windows: amd64]
Compiled at 2021-10-19
Copyright (c) 2006-2021 by Andreas Rumpf

active boot switches: -d:release

Out of curiosity i also tried it with a seq[cstring], this fails in a different way:

import genny

proc getDatas*(): seq[string] =
  result = @["a", "b", "c"]

exportSeq seq[string]:
  discard

proc getDatas2*(): seq[cstring] =
  result = @["a".cstring, "b", "c"]

exportSeq seq[cstring]:
  discard

exportProcs:
  getDatas
  getDatas2

writeFiles("bindings", "ttt")
include bindings/internal

PS C:\Users\david\projects\gennyt> nim c --app:lib -d:release --gc:orc .\ttt.nim

In [1]: import ttt
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [1], in <module>
----> 1 import ttt

File ~\projects\gennyt\bindings\ttt.py:124, in <module>
    121 dll.ttt_seq_cstring_len.restype = c_longlong
    123 dll.ttt_seq_cstring_get.argtypes = [SeqCstring, c_longlong]
--> 124 dll.ttt_seq_cstring_get.restype = cstring
    126 dll.ttt_seq_cstring_set.argtypes = [SeqCstring, c_longlong, cstring]
    127 dll.ttt_seq_cstring_set.restype = None

NameError: name 'cstring' is not defined

@enthus1ast
Copy link
Author

if you like i can put this into a new issue.

@guzba
Copy link
Collaborator

guzba commented Feb 6, 2022

We do not support exporting cstring directly from Nim right now. It can be added but I'm not going to right now. Looking into at the access violation.

@guzba
Copy link
Collaborator

guzba commented Feb 6, 2022

I see the issue. Seqs were not checking to see if they needed to do type conversions for import/export of the type they hold, like procs were already in genny. Unfortunately for your testing, string is one of the few cases that need conversion so I've got that fixed now in a PR.

@guzba
Copy link
Collaborator

guzba commented Feb 6, 2022

One small thing, I suggest using --tlsEmulation:off comple flag on Windows. It is a bad default to have that enabled and was fixed in 1.6.2 (https://nim-lang.org/blog/2021/12/17/version-162-released.html), but that regressed elsewhere.

@enthus1ast
Copy link
Author

thank you @guzba this works!

There is just one little thing, if i loop through the seq, i receive a NoneType error after the last element:

C:\Users\david\projects\gennyt\bindings>ipython
Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.0.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import ttt

In [2]: d = ttt.get_datas()

In [3]: for l in d:
   ...:     print(l)
a
b
c
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Input In [3], in <module>
----> 1 for l in d:
      2     print(l)

File ~\projects\gennyt\bindings\ttt.py:35, in SeqString.__getitem__(self, index)
     34 def __getitem__(self, index):
---> 35     return dll.ttt_seq_string_get(self, index).decode("utf8")

AttributeError: 'NoneType' object has no attribute 'decode'

In [4]:                                                                                                                                

i think this is not such a big issue since one can use this construct:

In [15]: for idx in range(0, len(d)):
    ...:     print(d[idx])

@guzba
Copy link
Collaborator

guzba commented Feb 7, 2022

For some reason for l in d: is reading past the end of the seq. I don't know why Python is doing that with that loop construct. Maybe there is some Python object func we need to override or something? Investigation needed.

@guzba
Copy link
Collaborator

guzba commented Feb 7, 2022

Ok, figured out the issue. We need a custom Iterator + override __iter__ on our Seq Python classes. Working on this quick now.

@guzba guzba mentioned this issue Feb 7, 2022
@enthus1ast
Copy link
Author

thank you @guzba it works fine now!

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

3 participants