dropbox / djinni

A tool for generating cross-language type declarations and interface bindings.
Apache License 2.0
2.88k stars 487 forks source link

How to use typedef type in Djinni IDL? #399

Closed aksswami closed 6 years ago

aksswami commented 6 years ago

I am using Djinni IDL to generate my C++ interfaces as well as Objc and Java bridging code. I am using the same interfaces with SWIG on windows to bind it with C#.

Window API and .Net API uses UTF-16 (wide string, wstring), so I am using Djinni flag --cpp-use-wide-strings for this.

The problem is, I have to generate two kinds of interfaces one with "std::string" and other with "std::wstring". And use #ifdef in include statements to include one or other generated interface. In my C++ code everywhere I am using typedef string_t std::string & typedef string_t std::wstring, but not sure how can I use "string_t" in Djinni IDL to generate with this type.

I looked at Djinni YAML to add a custom type, but not able to think how to do this for the above use case. How can we generate single interface file for this, as I don't want to clutter the code with #ifdef for same header file? Also generating two set just for string type difference.

jonmcclung commented 6 years ago

Not a real answer, but always remember you can write a script to modify the generated files with, for example, sed and have it automatically run whenever you regenerate.

aksswami commented 6 years ago

@jonmcclung Yes, that is a possible solution. But If this can be handled with Djinni in some way that would be a great and clean solution. Otherwise every extra step we include in our build process complicate the process.

paulocoutinhox commented 6 years ago

Problems like this was solved if djinni team convert it to use templates: https://github.com/dropbox/djinni/issues/368

Instead of generate code inside the main code logic.

artwyman commented 6 years ago

I'm not sure how you see these #ifdefs actually being used in the generated code. Regardless of what the C++ headers contain, Djinni needs to generate different code for std::string vs. std::wstring, because they need different conversion steps to/from Java/ObjC. It's probably possible to make more of that code generic/common with templates instead of #ifdefs, but it's never been a goal for Djinni to support both string types at once.

aksswami commented 6 years ago

@artwyman The #ifdefs are not in generated code, but in implementation code of generated interfaces. Anyway, I understand that conversion requires different steps for std::string and std::wstring.

For most of the platform OSX, iOS, Android std::string and it's binding works fine. Only for Windows where we need to bridge the code with C#, we are facing this issue. Maybe we can somehow specify which string version should the bridging needs to be generated. Correct me if I am wrong on something here.

aksswami commented 6 years ago

I tried two approaches for this

  1. Generate separate interfaces and records, one for std::string and other std::wstring. Now, I include the generated file to target based on the platform and in C++ code I am using #ifdef platform to include the specific header.
  2. I have modified the djinni to generate the record and interface with string_t type, which is typedef over std::string and std::wstring based on the platform. This typedef will be defined in a header file, which needs to be included in all the files where string_t is used. One can provide a path to this string_t header and this will be included automatically in generated code.

Please check https://github.com/aksswami/djinni/tree/string-typedef for more details. Thanks, everyone for your suggestion. Closing the issue. If anyone has any other idea, suggestion are welcome.