Re: Package permission and symbol resolution

2014-04-23 Thread Marco Leise via Digitalmars-d
Am Tue, 22 Apr 2014 18:07:21 +1000
schrieb Manu via Digitalmars-d digitalmars-d@puremagic.com:

   extern (C) void func(const(char)* pString);

By the way: What about adding nothrow there?

-- 
Marco



Package permission and symbol resolution

2014-04-22 Thread Manu via Digitalmars-d
So I've restructured one of my projects which is a C library bindings,
but also with some D-ification.

I separated it into 2 parts, the raw binding parts, and the api
enhancements, the module structure looks like this:

The Raw C binding part:

pkg/c/module.d:

  pkg.c.module;

  struct ModuleStruct
  {
package:
  int privateParts;
  }

  extern (C) void func(const(char)* pString);


And the wrapping layer; public import's the raw C bindings, which is
meant to make the C API available too while adding some sugar for
convenience.

pkg/module.d:

  pkg.module;

  public import pkg.c.module;

  void func(const(char)[] str)
  {
pkg.c.module.func(str.toStringz);
  }

  void func2(ref ModuleStruct s)
  {
s.privateParts += 10;
  }


I have a bunch of surprising problems.

1. Error: struct pkg.c.module.ModuleStruct member privateParts is not accessible

pkg.module can't access pkg.c.module.ModuleStruct.privateParts. Isn't
that what 'package' protection is for? My sugar wrapping module needs
to be able to access the private bits of the raw binding module, which
I don't want to pollute with sugar directly (since it would ideally be
generated by a generator and reflect only a pure C binding).

2. In client code, when I call for instance, func(string.ptr), which
has 2 overloads: 'extern (C) void func(const(char)*)' and 'void
func(const(char)[])', it doesn't seem to resolve the function
correctly:

Error: pkg.module.func at pkg\module.d(14) conflicts with
pkg.c.module.func at pkg\c\module.d
Error: function pkg.module.func (const(char)[] str) is not callable
using argument types (immutable(char)*)

Obviously, the other overload (pkg.c.module.func) can receive
immutable(char)* though, but it just ignores it rather than choosing
to call the appropriate overload.
What's really weird, is if I pass a string instead: func(string[]),
it picks the other incorrect overload.

Error: cannot implicitly convert expression (func(string[])) of type
const(char)[] to const(char)*


I've changed lots of random things, but I can't seem to resolve this cleanly.
What have I missed? It must be something simple.
This must be a common problem. I would imagine basically anyone who
wants to add sugar to a C binding would do it this way to avoid
polluting of the raw binding code?
Is there an alternative recommended practise?


Re: Package permission and symbol resolution

2014-04-22 Thread Manu via Digitalmars-d
On 22 April 2014 18:07, Manu turkey...@gmail.com wrote:
 So I've restructured one of my projects which is a C library bindings,
 but also with some D-ification.

 I separated it into 2 parts, the raw binding parts, and the api
 enhancements, the module structure looks like this:

 The Raw C binding part:

 pkg/c/module.d:

   pkg.c.module;

Should read: module pkg.c.module;


   struct ModuleStruct
   {
 package:
   int privateParts;
   }

   extern (C) void func(const(char)* pString);


 And the wrapping layer; public import's the raw C bindings, which is
 meant to make the C API available too while adding some sugar for
 convenience.

 pkg/module.d:

   pkg.module;

And: module pkg.module;


   public import pkg.c.module;

   void func(const(char)[] str)
   {
 pkg.c.module.func(str.toStringz);
   }

   void func2(ref ModuleStruct s)
   {
 s.privateParts += 10;
   }


Re: Package permission and symbol resolution

2014-04-22 Thread John Colvin via Digitalmars-d
On Tuesday, 22 April 2014 at 08:07:32 UTC, Manu via Digitalmars-d 
wrote:
So I've restructured one of my projects which is a C library 
bindings,

but also with some D-ification.

I separated it into 2 parts, the raw binding parts, and the api
enhancements, the module structure looks like this:

The Raw C binding part:

pkg/c/module.d:

  pkg.c.module;

  struct ModuleStruct
  {
package:
  int privateParts;
  }

  extern (C) void func(const(char)* pString);


And the wrapping layer; public import's the raw C bindings, 
which is
meant to make the C API available too while adding some sugar 
for

convenience.

pkg/module.d:

  pkg.module;

  public import pkg.c.module;

  void func(const(char)[] str)
  {
pkg.c.module.func(str.toStringz);
  }

  void func2(ref ModuleStruct s)
  {
s.privateParts += 10;
  }


I have a bunch of surprising problems.

1. Error: struct pkg.c.module.ModuleStruct member privateParts 
is not accessible


pkg.module can't access pkg.c.module.ModuleStruct.privateParts. 
Isn't

that what 'package' protection is for?


package protection allows access from the current package and 
subpackages (pkg.c.* in this case), but not to anyone further up 
the tree (pkg.someModule).


It would be nice one could write `protected(packageName)` to have 
better control over this.



The rest of your problems are, I think, explained here: 
http://dlang.org/hijack.html


Re: Package permission and symbol resolution

2014-04-22 Thread Manu via Digitalmars-d
On 22 April 2014 19:16, John Colvin via Digitalmars-d
digitalmars-d@puremagic.com wrote:
 On Tuesday, 22 April 2014 at 08:07:32 UTC, Manu via Digitalmars-d wrote:

 So I've restructured one of my projects which is a C library bindings,
 but also with some D-ification.

 I separated it into 2 parts, the raw binding parts, and the api
 enhancements, the module structure looks like this:

 The Raw C binding part:

 pkg/c/module.d:

   pkg.c.module;

   struct ModuleStruct
   {
 package:
   int privateParts;
   }

   extern (C) void func(const(char)* pString);


 And the wrapping layer; public import's the raw C bindings, which is
 meant to make the C API available too while adding some sugar for
 convenience.

 pkg/module.d:

   pkg.module;

   public import pkg.c.module;

   void func(const(char)[] str)
   {
 pkg.c.module.func(str.toStringz);
   }

   void func2(ref ModuleStruct s)
   {
 s.privateParts += 10;
   }


 I have a bunch of surprising problems.

 1. Error: struct pkg.c.module.ModuleStruct member privateParts is not
 accessible

 pkg.module can't access pkg.c.module.ModuleStruct.privateParts. Isn't
 that what 'package' protection is for?


 package protection allows access from the current package and subpackages
 (pkg.c.* in this case), but not to anyone further up the tree
 (pkg.someModule).

 It would be nice one could write `protected(packageName)` to have better
 control over this.

Yeah, this seems like a problem, particularly since precisely what I'm
doing seems intuitive and desirable to me.
Are there other patterns to separate the sugar from the raw binding?
If the binding is generated, it can't coexist with the sugar or it'll
be overwritten each time.


 The rest of your problems are, I think, explained here:
 http://dlang.org/hijack.html

Ah ha!
in order to overload functions from multiple modules together, an
alias statement is used to merge the overloads

I've actually read this article before, but I forgot that detail.
Cheers mate! :)


Re: Package permission and symbol resolution

2014-04-22 Thread Manu via Digitalmars-d
On 22 April 2014 21:00, Manu turkey...@gmail.com wrote:
 On 22 April 2014 19:16, John Colvin via Digitalmars-d
 The rest of your problems are, I think, explained here:
 http://dlang.org/hijack.html

 Ah ha!
 in order to overload functions from multiple modules together, an
 alias statement is used to merge the overloads

 I've actually read this article before, but I forgot that detail.
 Cheers mate! :)

Well, it worked in some cases...

How's this for a great error:
  Error: fuji.c.MFDebug.MFDebug_Warn at
D:\WinDev\fuji\dist\include\d2\fuji\c\MFDebug.d(38) conflicts with
fuji.c.MFDebug.MFDebug_Warn at
D:\WinDev\fuji\dist\include\d2\fuji\c\MFDebug.d(38)

Precisely the same symbol in precisely the same file are apparently in
conflict...
It seems it all gets confused when a file is imported via multiple
indirect means.

For instance:

B public imports A, B overloads some function in A and must make it
explicit using the rule you lank me to: alias finc = A.func;
If some client imports B, it is now working as expected; the overload
in A and B are both accessible.

But let's say there is also C which public imports A. C does not
overload anything A, so there's no need for the alias trick.

Client imports B and C (but not A). It seems that now A via C is in
conflict with A via B, even though B provides the alias to explicitly
satisfy the anti-hijacking rule. The same function reachable via C
stimulates the anti-hijacking error again even though it was addressed
in B where the overload was specified.