Hi,
what do you think about an optional parameter to compile nim code into its own namespace "Nim" (or configurable). When compiling nim code together with a big c++ library it is very likely to get name clashes with the existing code - for example names like TFrame or Exception are used very often.
I am trying to use Embarcadero C++ Builder with Nim. The problem is that by default C++ Builder pulls in all namespaces. So you have name clashes for example with TFrame or Exception. There is a way to avoid this by defining DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE which should prevents this. But still it is APITA to work with this colliding names and till now I can only compile with -d:release. I think it would get easier if the generated Nim code would be wrapped into its own namespace Nim. This means the #include "nimbase.h" and the generated code
to illustrate my problem in the following code I need to include uFNimHelloCBuilder.h in order to use TForm2, but this needs to pull in some namespaces of the VCL which pulls ins TFrame for example. This uFNimHelloCBuilder.h is managed by the C++ Builder and uses only unqualified names like TForm or TButton or TFrame...
import vcl/stdctrls, vcl/forms, vcl/sysutils, strutils
{.emit:"""/*TYPESECTION*/
using namespace System;
using namespace Vcl;
using namespace Vcl::Controls;
using namespace Vcl::Stdctrls;
using namespace Vcl::Forms;
#include "uFNimHelloCBuilder.h"
""".}
{.this:self.}
type
TForm2* {.importcpp:"TForm2" .} = object of TForm
Button1*: ptr TButton
Label1*: ptr TLabel
TNotifyCode* = proc(self: ptr DelphiObject, sender: ptr DelphiObject) {.fastcall.}
var counter = 0
proc myClick(self: ptr TForm2, sender: ptr DelphiObject) {.fastcall.} =
Button1.Caption = "greetings from nim".capitalize
proc test(self: ptr TForm2) {.exportc.} =
inc counter
Button1.Caption = Button1.Caption & $counter
var mycall: TMethod
mycall.Data = self
#var call: TNotifyCode = cast[TNotifyCode](myClick)
mycall.Code = cast[TNotifyCode](myClick)
Label1.OnClick := mycall
I did some deeper research. wrapping the nimbase.h would be wrong it is enough to wrap the TFrame stuff conditionally into a namespace Nim. In the generated code the wrapping should start after the #undef unix or before the first declaration until the end.
Would you accept a pull request when I try to do the change ?
With my manual patches I can compile in debug and release mode, and the above code reduces to:
import vcl/stdctrls, vcl/forms, vcl/sysutils, strutils
{.this:self.}
type
TForm2* {.importcpp:"TForm2", header:"uFNimHelloCBuilder.h".} = object of TForm
Button1*: ptr TButton
Label1*: ptr TLabel
TNotifyCode* = proc(self: ptr DelphiObject, sender: ptr DelphiObject) {.fastcall.}
var counter = 0
proc myClick(self: ptr TForm2, sender: ptr DelphiObject) {.fastcall.} =
Button1.Caption = "greetings from nim".capitalize
proc test(self: ptr TForm2) {.exportc, fastcall.} =
inc counter
Button1.Caption = Button1.Caption & $counter
var mycall: TMethod
mycall.Data = self
#var call: TNotifyCode = cast[TNotifyCode](myClick)
mycall.Code = cast[TNotifyCode](myClick)
Label1.OnClick := mycall