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

meta: dealing with language differences between C++ and nim #18

Open
6 tasks
haxscramper opened this issue Oct 17, 2021 · 4 comments
Open
6 tasks

meta: dealing with language differences between C++ and nim #18

haxscramper opened this issue Oct 17, 2021 · 4 comments
Labels
C++ Issues related specifically to C++ processing open for design discussion question Further information is requested

Comments

@haxscramper
Copy link
Owner

haxscramper commented Oct 17, 2021

Additional related links

@haxscramper haxscramper added open for design discussion question Further information is requested C++ Issues related specifically to C++ processing labels Oct 17, 2021
@haxscramper haxscramper changed the title meta: dealing with language diffenrces between C++ and nim meta: dealing with language differences between C++ and nim Oct 17, 2021
@haxscramper
Copy link
Owner Author

haxscramper commented Nov 23, 2021

Const is a huge PITA - I dynlib deals with the inconsistencies by generating code like (it just ignores const-ness of the argument)

typedef N_CDECL_PTR(NCSTRING, tyProc__cTCodr69cPNr9chtH7apXJYg) (NCSTRING s);
Dl_4294968796_ = (tyProc__cTCodr69cPNr9chtH7apXJYg) nimGetProcAddr(TM__xDZurH9b9cD5SoY3HyXHwqcw_2, "wave_unescapeIncludeToken");

and then calling it, but if I try to do a simple importc it seems that I either have to header: the procedure import, or make sure the header is never imported, otherwise I get a conflicting types error.

wave_c_api.h defines types, I import them using header:, but at the same time for regular procedures it is more problematic.

@haxscramper
Copy link
Owner Author

haxscramper commented Nov 23, 2021

[...]/@mnim_cxx_const_main.nim.c:63:15: error: conflicting types for ‘get_cstring_link’; have ‘void(char *)’
   63 | N_CDECL(void, get_cstring_link)(NCSTRING str);
      |               ^~~~~~~~~~~~~~~~
/home/test/.choosenim/toolchains/nim-1.6.0/lib/nimbase.h:201:44: note: in definition of macro ‘N_CDECL’
  201 | #    define N_CDECL(rettype, name) rettype name
      |                                            ^~~~
In file included from [...]: note: previous declaration of ‘get_cstring_link’ with type ‘void(const char *)’
    6 | void get_cstring_link(const char* cstring);
      |      ^~~~~~~~~~~~~~~~

nim_cxx_const_main.nim

const
  h = "lib.h"
  l = "liblib.so"

type
  str {.importc: "struct str", header: h.} = object
    field: cint

echo str()

proc get_cstring_dl(str: cstring) {.dynlib: l, importc: "get_cstring_dl".}

get_cstring_dl(nil)

proc get_cstring_link(str: cstring) {.cdecl, importc: "get_cstring_link".}

get_cstring_link(nil)

xmake.lua

target("lib")
    set_kind("shared")
    add_files("lib.c")
    set_targetdir(os.scriptdir())

target("main")
    set_kind("binary")
    add_deps("lib")
    add_files("nim_cxx_const_main.nim")
    add_links("lib")
    set_targetdir(os.scriptdir())

lib.c

void get_cstring(const char* cstring) {}
void get_cstring_link(const char* cstring) {}

lib.h

struct str {
    int field;
};

void get_cstring_dl(const char* cstring);
void get_cstring_link(const char* cstring);

Reproduce with xmake


nodecl fixes that for C backend, but in C++ I get ‘get_cstring_link’ was not declared in this scope int T4_ = get_cstring_link(((NCSTRING) NIM_NIL));

@haxscramper
Copy link
Owner Author

haxscramper commented Nov 23, 2021

I think this could've been trivially solved if Const[T] {.importcpp: "const '*0".} worked correctly, but right now it

  1. Does not work (generates const '*0 T1_;)
  2. Implicitly promotes file to the C++ backend, failing compilation

Can this be fixed by making importcpp: work the same way in procs and type imports?

@haxscramper
Copy link
Owner Author

I can wrap each type twice - as a regular object and as a const. This approach is of course insane, since I can also have ptr T, ptr ptr T, ref T and so on, but this way nim would generate correct procedure prototypes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C++ Issues related specifically to C++ processing open for design discussion question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant