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
nice_agent_get_selected_pair in gintro/nice is declared incorrectly #99
Comments
Thanks for reporting. I don't know much about libnice myself but I will try to investigate that issue soon. |
OK, you may try with nimble install gintro@#head For this issue it seems that the bug was only that NiceCandidate was not marked as "light" object which needs no proxy object. We have a list of that entities in gen.nim generator script and I added one line for this fix. So that type has fields now, and we generally use plain stack variables of that type and do not allocate it with a function on the heap. I hope it will work for you now. (We can not avoid these need for manually fixes, I had a discussion with Mr. Droege from Rust team about these issues.) And we have support for optional out var parameters now. That was some more work, and it is not much tested yet. A lot of code has changed. There is at least one known bug -- a few procs have optional seq parameter, that would crash if no value is provided. We will fix later. |
Thank you for your fix! type
Candidate* {.pure, byRef.} = object
`type`*: CandidateType
transport*: CandidateTransport
`addr`*: Address00
baseAddr*: Address00
priority*: uint32
streamId*: uint32
componentId*: uint32
foundation*: array[33, int8]
username*: cstring
password*: cstring And this is gintro generated code that define type
Address00* {.pure.} = object
Address* = ref object
impl*: ptr Address00
ignoreFinalizer*: bool
This is gintro generated code that declares proc nice_agent_get_selected_pair(self: ptr Agent00; streamId: uint32; componentId: uint32;
local: Candidate; remote: Candidate): gboolean {.
importc, libprag.}
proc getSelectedPair*(self: Agent; streamId: int; componentId: int;
local: Candidate; remote: Candidate): bool =
toBool(nice_agent_get_selected_pair(cast[ptr Agent00](self.impl), uint32(streamId), uint32(componentId), local, remote)) But
Thus, proc nice_agent_get_selected_pair(self: ptr Agent00; streamId: uint32; componentId: uint32;
local: var ptr Candidate; remote: var ptr Candidate): gboolean {.
importc, libprag.}
proc getSelectedPair*(self: Agent; streamId: int; componentId: int;
local: var ptr Candidate; remote: var ptr Candidate): bool =
toBool(nice_agent_get_selected_pair(cast[ptr Agent00](self.impl), uint32(streamId), uint32(componentId), local, remote)) And var local, remote: ptr Candidate
let ret = agent.getSelectedPair(streamId, componentId, local.addr, remote.addr)
let port = local.`addr`.port
# local and remote must not be freed. |
OK, I have finished the GtkLabel example in the GTK4 book finally (http://ssalewski.de/gtkprogramming.html#_label) so I can work again on your issue. You are right of course, the nice.Address data type has to be a "light" type with fields and without a proxy object. That type is reported by gobject-introspection as struct with zero fields. But it has a field of type union. So we have to create that type manually. All that is not that easy and straight forward, so I will convert your linked C code example from above to Nim and test it myself. I will try to do it in the next few days. |
That is really hard :-) I think I will finally get it working, but I wonder if it really makes much sense to write so much low level code tightly coupled to a low level C lib in Nim. |
import nativesockets
type
# See https://gitlab.freedesktop.org/libnice/libnice/-/blob/master/agent/address.h
Address* {.union.} = object
`addr`*: SockAddr
ip4*: Sockaddr_in
ip6*: Sockaddr_in6
If libnice provided setters and getters to access each fields of |
Thanks. Yesterday I tried to get GSList support working, as that C example used GSList. Have still to test. nice.Candidate in now again a heavy object with proxy, but for Candidate00 we generate fields, so we can access fields like cand.impl.priority = uint32(parseInt(tokens[1])). Ugly, but we can create access functions manually later. Then there is glib.ioAddWatch() which adds a callback, I think I have to create a macro for this. I hope I will get is working this weekend. |
OK, you can try again :-) The example program https://github.com/StefanSalewski/gintro/blob/master/examples/gtk3/simple_example.nim looks fine now, compiles and seems to have similar output as C version. But again I can not test on windows or test real function of that program as I have currently only one Linux computer available. I added some new macros in files gimpglib.nim and gimplnice.nim. Macros is always hard, seems to work, but maybe you can improve them yourself. And you may test with and without the last optional parameter and for different types of the optional parameter. I have not done all that tests. For NiceAddress I used your suggestion, and I had some discussion with Mr. Droege, see https://discourse.gnome.org/t/size-of-nicecandidate-of-libnice/4913 |
Thank you for your hard work! I tried to run simple_example.nim but parsing remote candidate generate error. You can test with only one computer. If you run 2 libnice programs at same time on one PC, they choose different port (looks like they choose port randomly) and they can communicate each other after they got remote candidates. |
Thanks for instructions to test it. I have just launched the C version, that one works. Will try to fix the Nim version today. |
Found a few typos. Main bug is use of
I think it was never tested before, and obviously do not work for NiceCandidate as NiceCandidate in not a GObject. Will try to fix it today. If I remember correctly I used the discard statement because it was unclear which objects have the impl field, so I restrict to strings and GObjects that time. |
I have fixed the typos, but when I try to make seq2GSList() working compile fails with message: Error: template instantiation too nested That is very ugly, I have no idea which really causes that error. For now I will send you the file with fixed typos:
Was mainly some small typos and a missing break statement:
But with
it fails to compile with Error: template instantiation too nested Will ask on Nim forum and try again later. Only idea is to try a non generic seq2GSList for NiceCandidate in nice.nim module. Will maybe try later. |
Well I found two more errors, both will take some time to fix. Will try to do it tomorrow. |
I don't get that compile error. proc seq2GSList*[T](s: seq[T]): ptr glib.SList =
var l: ptr glib.SList
var i = s.len
while i > 0:
dec(i)
when T is gobject.Object or compiles(T.impl):
l = g_slist_prepend(l, s[i].impl)
elif T is cstring:
l = g_slist_prepend(l, s[i]) # cstring
else:
{.error: "seq2GSList was called with unsupported type".}
return l |
proc nice_agent_get_selected_pair(self: ptr Agent00; streamId: uint32; componentId: uint32;
local: ptr Candidate00; remote: ptr Candidate00): gboolean {.
importc, libprag.}
proc getSelectedPair*(self: Agent; streamId: int; componentId: int;
local: Candidate; remote: Candidate): bool =
toBool(nice_agent_get_selected_pair(cast[ptr Agent00](self.impl), uint32(streamId), uint32(componentId), cast[ptr Candidate00](local.impl), cast[ptr Candidate00](remote.impl))) They need to be fixed like this: proc nice_agent_get_selected_pair(self: ptr Agent00; streamId: uint32; componentId: uint32;
local: var ptr Candidate00; remote: var ptr Candidate00): gboolean {.
importc, libprag.}
proc getSelectedPair*(self: Agent; streamId: int; componentId: int;
local: Candidate; remote: Candidate): bool =
toBool(nice_agent_get_selected_pair(cast[ptr Agent00](self.impl), uint32(streamId), uint32(componentId), local.impl, remote.impl)) It is used like this code: var
local = Candidate(ignoreFinalizer: true)
remote = Candidate(ignoreFinalizer: true)
if getSelectedPair(agent, streamId, componentId, local, remote):
|
I told you I will fix it. Done. Works for me. Please test with nimble install gintro@#head |
Thank you!
|
Unfortunately I can not help you for your Windows issue, I have no idea. One reason could be that gintro does not work for 32 bit OS, I think no one ever has tested gintro with 32 bit. But I assume that your windows is 64 bit. For the "Error: template instantiation too nested" I found the reason, it is the "when (compiles do: import gintro/gtk):" statement. That one seems to be very broken, see https://forum.nim-lang.org/t/7222 I will add your libnice_simple_test.nim to the gtk3 examples tomorrow. |
It seems we don't need to check existance of I have installed gtk3 and gtk4 using (MSYS2)[https://www.msys2.org] with following command:
Then I reinstalled gintro with I changed following import statements in when (compiles do: import gintro/gtk):
import gintro/[gtk, glib, gobject, gio, nice]
else:
import gintro/[dummygtk, glib, gobject, gio, nice] # For windows with glib but no gtk to import gintro/[dummygtk, glib, gobject, gio, nice] # For windows with glib but no gtk and it compils and works without error. |
Thank you for supporting libnice!
libnice has
nice-agent-get-selected-pair
function andlocal
andremote
parameters areNiceCandidate **
type.https://libnice.freedesktop.org/libnice/NiceAgent.html#nice-agent-get-selected-pair
But
local
andremote
parameters are declared asptr Candidate00
in gintro/nice and cannot get pointer toNiceCandidate
.This is gintro/nice code that wrap
nice-agent-get-selected-pair
function.nice_agent_get_selected_pair
function returns the address of existingNiceCandidate
object by writing it tolocal
andremote
arguments.So it may not be freed by caller.
You can see how to use
nice_agent_get_selected_pair
incb_component_state_changed
function in this libnice C example code.libnice doesn't provide functions to query a value of
NiceCandidate
's fields.So I need to access fields of
NiceCandidate
directly to get an address or other data inNiceCandidate
.In
cb_component_state_changed
andprint_local_data
functions in simple-example.c in libnice, it readsNiceCandidate
's fields directly.https://gitlab.freedesktop.org/libnice/libnice/-/blob/master/examples/simple-example.c
But
Candidate00
type in gintro/nice wrapsNiceCandidate
type without fields.I think this can be fixed by adding following type in gintro/nice:
and declare
nice_agent_get_selected_pair
like this:and
getSelectedPair
like this:or
The text was updated successfully, but these errors were encountered: