Interfacing with C++

2018-02-03 Thread infinityplusb via Digitalmars-d-learn

Hi all

I'm looking to try and write an interface to C++, but given I'm a 
casual dabbler in D, it's slightly beyond my current ability in 
terms of both C++ and D!


As a leg up, how would one translate something like this from C++ 
to D?


`typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, 
void* userdata );`


From my basic understanding I assumed something like:

`alias CvCmpFunc = Typedef!(int) ; `

but then I'm stuck as to where the rest of the parameters would 
get passed?
Do I just declare it as a function instead? That wasn't my 
understanding of reading how typedefs worked, however so I'm a 
little confused.


Any help would be appreciated.

Regards


Interfacing with C++

2014-11-01 Thread Shriramana Sharma via Digitalmars-d-learn
Hello. I really really need to be able to interface well with a C++
library which contains lots of classes if I am going to further invest
time into D.

Now from the http://dlang.org/cpp_interface I find out the current
status of built-in C++ interfacing support. I'm working on Linux so
using the COM support is not an option for me (whatever COM may be!).

A few queries:

1) How mature is the SWIG support for wrapping a library into D?
Specifically does the above SWIG support take advantage of the
built-in C++ support features like connecting directly to virtual
functions?

2) Is there any further work underway to implement support for static
and non-virtual class member functions? Or is this not at all
possible? If so, why?

3) The page speaks about having to integrate an entire C++ compiler
into the D compiler. Could the usage of libclang help here in having
to avoid writing a new C++ compiler module or am I talking through my
(non-existent) hat?

-- 
Shriramana Sharma ஶ்ரீரமணஶர்மா श्रीरमणशर्मा



Re: Interfacing with C++

2018-02-04 Thread rikki cattermole via Digitalmars-d-learn

On 04/02/2018 7:54 AM, infinityplusb wrote:

Hi all

I'm looking to try and write an interface to C++, but given I'm a casual 
dabbler in D, it's slightly beyond my current ability in terms of both 
C++ and D!


As a leg up, how would one translate something like this from C++ to D?

`typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* 
userdata );`


 From my basic understanding I assumed something like:

`alias CvCmpFunc = Typedef!(int) ; `

but then I'm stuck as to where the rest of the parameters would get passed?
Do I just declare it as a function instead? That wasn't my understanding 
of reading how typedefs worked, however so I'm a little confused.


Any help would be appreciated.

Regards


alias CvCmpFunc = extern(C /* I think */) int function(const void* a, 
const void* b, void* userdata);


Re: Interfacing with C++

2018-02-04 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 4 February 2018 at 07:54:12 UTC, infinityplusb wrote:

Hi all

I'm looking to try and write an interface to C++, but given I'm 
a casual dabbler in D, it's slightly beyond my current ability 
in terms of both C++ and D!


As a leg up, how would one translate something like this from 
C++ to D?


`typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* 
b, void* userdata );`


From my basic understanding I assumed something like:

`alias CvCmpFunc = Typedef!(int) ; `

but then I'm stuck as to where the rest of the parameters would 
get passed?
Do I just declare it as a function instead? That wasn't my 
understanding of reading how typedefs worked, however so I'm a 
little confused.


Any help would be appreciated.



First, you have to understand how CV_CDECL is defined. This is 
going to determine the calling convention that functions pointed 
to by CvCmpFunc will have. Assuming it's defined to cdecl, the 
standard C calling convention (which I'm guess it is) then your D 
definition needs to be extern(C). If it's stdcall, then you need 
extern(Windows). If it's empty, then you need extern(C++).


Second, because this is a function pointer you're declaring, you 
need to use D's function pointer declaration syntax.


Third, we don't need to use the Typedef template for this. alias 
alone is fine.


So assuming CV_CDECL is cdecl, this should do it:

extern(C) alias CvCmpFunc = int function(const(void)*, 
const(void)*, void*);


Re: Interfacing with C++

2018-02-04 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 4 February 2018 at 08:17:31 UTC, Mike Parker wrote:



So assuming CV_CDECL is cdecl, this should do it:

extern(C) alias CvCmpFunc = int function(const(void)*, 
const(void)*, void*);


Assuming this is OpenCV, Looking at [1], it's cdecl only on 
Windows. Empty everywhere else. So since OpenCV is a C++ library 
these days, I guess it needs to be declared like this:


version(Windows)
extern(C) alias CvCmpFunc = int function(const(void)*, 
const(void)*, void*);

else
extern(C++) alias CvCmpFunc = int function(const(void)*, 
const(void)*, void*);


Though, I'm curious why anyone would want to declare a callback 
in a C++ program as cdecl only on Windows and use the default C++ 
convention everywhere else. I suggest you dig into it and make 
sure that's what's intended. And good luck binding to OpenCV!



[1] 
https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types_c.h#L68


Re: Interfacing with C++

2018-02-04 Thread infinityplusb via Digitalmars-d-learn

On Sunday, 4 February 2018 at 08:33:20 UTC, Mike Parker wrote:

On Sunday, 4 February 2018 at 08:17:31 UTC, Mike Parker wrote:

Assuming this is OpenCV ...
it is, everyone keeps saying writing bindings in D is super easy 
...

I feel this is a slight simplification. :(


version(Windows)
extern(C) alias CvCmpFunc = int function(const(void)*, 
const(void)*, void*);

else
extern(C++) alias CvCmpFunc = int function(const(void)*, 
const(void)*, void*);

Sounds easy enough.

Though, I'm curious why anyone would want to declare a callback 
in a C++ program as cdecl only on Windows and use the default 
C++ convention everywhere else. I suggest you dig into it and 
make sure that's what's intended.



And good luck binding to OpenCV!

Thanks, I feel I'm going to need it ...


Re: Interfacing with C++

2018-02-04 Thread Seb via Digitalmars-d-learn

On Sunday, 4 February 2018 at 10:42:22 UTC, infinityplusb wrote:

On Sunday, 4 February 2018 at 08:33:20 UTC, Mike Parker wrote:

[...]
it is, everyone keeps saying writing bindings in D is super 
easy ...

I feel this is a slight simplification. :(


[...]

Sounds easy enough.


[...]



[...]

Thanks, I feel I'm going to need it ...


For C headers, you can use dstep to automatically generate the 
respective D header file: https://github.com/jacob-carlborg/dstep


Re: Interfacing with C++

2018-02-04 Thread rjframe via Digitalmars-d-learn
On Sun, 04 Feb 2018 08:33:20 +, Mike Parker wrote:

> Though, I'm curious why anyone would want to declare a callback in a C++
> program as cdecl only on Windows and use the default C++
> convention everywhere else. I suggest you dig into it and make sure
> that's what's intended. And good luck binding to OpenCV!

My guess would be that it's to prevent name mangling of functions in a 
generated DLL and the need for a DEF file.


Re: Interfacing with C++

2018-02-04 Thread Timothee Cour via Digitalmars-d-learn
Calypso (https://github.com/Syniurge/Calypso/) is the most promising
way to interface with C++, it requires 0 bindings and understands all
of C++ (templates etc); there are some caveats/kinks that are being
ironed out (and any help is welcome).


On Sun, Feb 4, 2018 at 4:37 AM, rjframe via Digitalmars-d-learn
 wrote:
> On Sun, 04 Feb 2018 08:33:20 +, Mike Parker wrote:
>
>> Though, I'm curious why anyone would want to declare a callback in a C++
>> program as cdecl only on Windows and use the default C++
>> convention everywhere else. I suggest you dig into it and make sure
>> that's what's intended. And good luck binding to OpenCV!
>
> My guess would be that it's to prevent name mangling of functions in a
> generated DLL and the need for a DEF file.


Re: Interfacing with C++

2018-02-05 Thread Kagamin via Digitalmars-d-learn

On Sunday, 4 February 2018 at 08:33:20 UTC, Mike Parker wrote:
Though, I'm curious why anyone would want to declare a callback 
in a C++ program as cdecl only on Windows and use the default 
C++ convention everywhere else. I suggest you dig into it and 
make sure that's what's intended. And good luck binding to 
OpenCV!



[1] 
https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types_c.h#L68


No, it's C everywhere, see 
https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types_c.h#L1774


Re: Interfacing with C++

2018-02-05 Thread Timothee Cour via Digitalmars-d-learn
https://github.com/opencv/opencv/issues/6585#issuecomment-221842441
snip:

> "C-API" is not supported and should be removed totally (but we have a lack of 
> resources to port this legacy C code to C++, so some of this code still 
> exists right now). Also huge part of fresh OpenCV functionality is missing in 
> "C-API".
There is no plan to fix this in OpenCV directly.

http://answers.opencv.org/question/17546/opencv-will-drop-c-api-support-soon/
snip:
> Shervin is right, the C API is not developed for a long time. All the new 
> stuff has the C++ API, and it is not backported to the C. So, C API becomes 
> obsolete and causes pain in the neck, since it should be maintained

I recommend trying out Calypso and helping ironing out any bugs you may find.


On Mon, Feb 5, 2018 at 3:15 AM, Kagamin via Digitalmars-d-learn
 wrote:
> On Sunday, 4 February 2018 at 08:33:20 UTC, Mike Parker wrote:
>>
>> Though, I'm curious why anyone would want to declare a callback in a C++
>> program as cdecl only on Windows and use the default C++ convention
>> everywhere else. I suggest you dig into it and make sure that's what's
>> intended. And good luck binding to OpenCV!
>>
>>
>> [1]
>> https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types_c.h#L68
>
>
> No, it's C everywhere, see
> https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types_c.h#L1774


Re: Interfacing with C++

2014-11-01 Thread Kagamin via Digitalmars-d-learn
You can see http://wiki.dlang.org/DIP61 and linked discussions. 
Static and virtual functions probably work. Constructors and 
destructors probably don't. What's difficult is multiple 
inheritance. The information on C++ support is largely considered 
private to the compiler team.


Re: Interfacing with C++

2014-11-02 Thread Kagamin via Digitalmars-d-learn
D.learn is about basics of D. Interfacing with C++ is an advanced 
topic, with feature set in flux, so I'd suggest to ask about it 
in http://forum.dlang.org/group/digitalmars.D group.


Callbacks and interfacing with C

2012-10-30 Thread Nick Sabalausky
Ok, a C function pointer like this:

struct MyStruct{
int (*foo)(int);
};

Translates to D as this:

struct MyStruct{
int function(int) foo;
}

But what about calling conventions? There isn't any "int extern(C)
function(int)" is there? Not sure if that would even make sense.

So do you just make sure that whatever func you assign to it is an
extern(C)? Or something else?



Interfacing with C++ Class named Object

2018-05-01 Thread Robert M. Münch via Digitalmars-d-learn
Hi, I'm mostly doing simple C-API wrappers around C++ code to access 
thigns from D. However, I wanted to try how far I can come using C++ 
directly.


I have the following C++ code in namespace N:

class Image : public Object {
Error create(int w, int h, uint32_t p) noexcept;
}
And I have the following D code:
extern (C++, N) {
 class Object {
 }
 class Image : public Object {
   uint create(int w, int h, uint pixelFormat);
 }
}
So frist problem I see is, that a C++ class names Object is pretty 
unfortunate as this is a reserved class name in D. And DMD doesn't seem 
to allow using Object inside a C++ scope (which IMO should be possible).
Am I right, that there is no chance to handle this case other than 
ranming the C++ base class?


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: Callbacks and interfacing with C

2012-10-30 Thread Alex Rønne Petersen

On 30-10-2012 11:13, Nick Sabalausky wrote:

Ok, a C function pointer like this:

 struct MyStruct{
 int (*foo)(int);
 };

Translates to D as this:

 struct MyStruct{
 int function(int) foo;
 }

But what about calling conventions? There isn't any "int extern(C)
function(int)" is there? Not sure if that would even make sense.

So do you just make sure that whatever func you assign to it is an
extern(C)? Or something else?



You generally do it this way:

alias extern (C) int function(int) MyFn;

struct MyStruct {
MyFn foo;
}

This makes sure the calling convention is correct. In general, calling 
convention is part of both the function signature and function pointer 
type - function pointers just default to extern (D).


--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


Re: Callbacks and interfacing with C

2012-10-30 Thread Nick Sabalausky
On Tue, 30 Oct 2012 11:15:55 +0100
Alex Rønne Petersen  wrote:

> On 30-10-2012 11:13, Nick Sabalausky wrote:
> > Ok, a C function pointer like this:
> >
> >  struct MyStruct{
> >  int (*foo)(int);
> >  };
> >
> > Translates to D as this:
> >
> >  struct MyStruct{
> >  int function(int) foo;
> >  }
> >
> > But what about calling conventions? There isn't any "int extern(C)
> > function(int)" is there? Not sure if that would even make sense.
> >
> > So do you just make sure that whatever func you assign to it is an
> > extern(C)? Or something else?
> >
> 
> You generally do it this way:
> 
> alias extern (C) int function(int) MyFn;
> 
> struct MyStruct {
>  MyFn foo;
> }
> 
> This makes sure the calling convention is correct. In general,
> calling convention is part of both the function signature and
> function pointer type - function pointers just default to extern (D).
> 

Hmm, that leads me to another Q:


extern(C): // <-- Note this

alias int function(int) MyFn;

struct MyStruct {
MyFn foo1;
int function(int) foo2;
}

void bar(int function(int) foo3) {...}

Which, if any, of foo1/foo2/foo3 are extern(C)? (I know bar definitely
is.)



Re: Callbacks and interfacing with C

2012-10-30 Thread bearophile

Nick Sabalausky:

Which, if any, of foo1/foo2/foo3 are extern(C)? (I know bar 
definitely is.)


A general comment: if you are not sure of the answer, then the 
programmer that will read your code will probably have similar 
problems. So in such cases it's better to try to not write that 
code.


Bye,
bearophile


Re: Callbacks and interfacing with C

2012-10-30 Thread Andrej Mitrovic
On 10/30/12, Nick Sabalausky  wrote:
> Which, if any, of foo1/foo2/foo3 are extern(C)? (I know bar definitely
> is.)

All of them.

void main()
{
pragma(msg, MyFn);
pragma(msg, typeof(MyStruct.foo2));
pragma(msg, typeof(bar));
}

extern (C) int function(int)
extern (C) int function(int)
extern (C) void(extern (C) int function(int) foo3)
extern (C) int function(int)
extern (C) int function(int)
extern (C) void(extern (C) int function(int) foo3)

It's because extern(C): leaks everywhere, whether on purpose or not.
It can be a benefit for writing shorter code, but when reading such
code it's easy to forget to check for an extern(C): declaration at the
top and just wrongly assume that it's all extern(D).


Re: Callbacks and interfacing with C

2012-10-30 Thread Jacob Carlborg

On 2012-10-30 18:44, Andrej Mitrovic wrote:


All of them.

void main()
{
 pragma(msg, MyFn);
 pragma(msg, typeof(MyStruct.foo2));
 pragma(msg, typeof(bar));
}

extern (C) int function(int)
extern (C) int function(int)
extern (C) void(extern (C) int function(int) foo3)
extern (C) int function(int)
extern (C) int function(int)
extern (C) void(extern (C) int function(int) foo3)

It's because extern(C): leaks everywhere, whether on purpose or not.
It can be a benefit for writing shorter code, but when reading such
code it's easy to forget to check for an extern(C): declaration at the
top and just wrongly assume that it's all extern(D).


It doesn't leak into local declarations in a function:

extern (C):

void foo ()
{
alias void function () Foo;

void function (int) a;
auto b = cast(void function ()) a;

pragma(msg, Foo);
pragma(msg, typeof(a));
pragma(msg, typeof(b));
}

void function()
void function(int)
void function()

--
/Jacob Carlborg


Re: Interfacing with C++ Class named Object

2018-05-01 Thread Timoses via Digitalmars-d-learn

On Tuesday, 1 May 2018 at 15:24:09 UTC, Robert M. Münch wrote:
Hi, I'm mostly doing simple C-API wrappers around C++ code to 
access thigns from D. However, I wanted to try how far I can 
come using C++ directly.


I have the following C++ code in namespace N:

class Image : public Object {
Error create(int w, int h, uint32_t p) noexcept;
}
And I have the following D code:
extern (C++, N) {
 class Object {
 }
 class Image : public Object {
   uint create(int w, int h, uint pixelFormat);
 }
}
So frist problem I see is, that a C++ class names Object is 
pretty unfortunate as this is a reserved class name in D. And 
DMD doesn't seem to allow using Object inside a C++ scope 
(which IMO should be possible).
Am I right, that there is no chance to handle this case other 
than ranming the C++ base class?


Would `pragma(mangle, ...)` work here?
https://dlang.org/spec/pragma.html#mangle


Re: Interfacing with C++ Class named Object

2018-05-01 Thread Robert M. Münch via Digitalmars-d-learn

On 2018-05-01 16:07:30 +, Timoses said:


On Tuesday, 1 May 2018 at 15:24:09 UTC, Robert M. Münch wrote:
Hi, I'm mostly doing simple C-API wrappers around C++ code to access 
thigns from D. However, I wanted to try how far I can come using C++ 
directly.


I have the following C++ code in namespace N:

class Image : public Object {
Error create(int w, int h, uint32_t p) noexcept;
}
And I have the following D code:
extern (C++, N) {
class Object {
}
class Image : public Object {
uint create(int w, int h, uint pixelFormat);
}
}
So frist problem I see is, that a C++ class names Object is pretty 
unfortunate as this is a reserved class name in D. And DMD doesn't seem 
to allow using Object inside a C++ scope (which IMO should be possible).
Am I right, that there is no chance to handle this case other than 
ranming the C++ base class?


Would `pragma(mangle, ...)` work here?
https://dlang.org/spec/pragma.html#mangle


Yes, great! Thanks. I could extend the code now. But I get a next problem:

extern (C++, b2d) {
 class AnyBase {
   bool isShared();
 }

 pragma(mangle, "Object");
 class b2dObject : AnyBase {
 }

 class Image : b2dObject {
 // class Image {
   uint create(int w, int h, uint pixelFormat);
 }
}

The linke complains about missing symbols:

error LNK2001: "public: virtual bool __cdecl 
b2d::AnyBase::isShared(void)" (?isShared@AnyBase@b2d@@UEBA_NXZ)
error LNK2001: "public: virtual unsigned int __cdecl 
b2d::Image::create(int,int,unsigned int)" 
(?create@Image@b2d@@UEAAIHHI@Z)


I have in my C++ link lib:

?isShared@AnyBase@b2d@@QEBA_NXZ which demangles to => public: BOOL 
__cdecl b2d::AnyBase::isShared(void)const __ptr64


So, the difference is the "virtual" specifier on the D side, while the 
C++ mangeling is missing this. I have this for many functions.


Any idea how to handle this?

--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: Interfacing with C++ Class named Object

2018-05-01 Thread Robert M. Münch via Digitalmars-d-learn

On 2018-05-01 17:14:53 +, Robert M. Münch said:


Yes, great! Thanks. I could extend the code now. But I get a next problem:

extern (C++, b2d) {
  class AnyBase {
bool isShared();
  }

  pragma(mangle, "Object");
  class b2dObject : AnyBase {
  }

  class Image : b2dObject {
  // class Image {
uint create(int w, int h, uint pixelFormat);
  }
}

The linke complains about missing symbols:

error LNK2001: "public: virtual bool __cdecl 
b2d::AnyBase::isShared(void)" (?isShared@AnyBase@b2d@@UEBA_NXZ)
error LNK2001: "public: virtual unsigned int __cdecl 
b2d::Image::create(int,int,unsigned int)" 
(?create@Image@b2d@@UEAAIHHI@Z)


I have in my C++ link lib:

?isShared@AnyBase@b2d@@QEBA_NXZ which demangles to => public: BOOL 
__cdecl b2d::AnyBase::isShared(void)const __ptr64


So, the difference is the "virtual" specifier on the D side, while the 
C++ mangeling is missing this. I have this for many functions.


Any idea how to handle this?


Answering myself. There is a final keyword missing:

 class Image : b2dObject {
 // class Image {
   final uint create(int w, int h, uint pixelFormat);
 }

With this it's working.

--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



interfacing with C: strings and byte vectors

2016-06-11 Thread yawniek via Digitalmars-d-learn

my C library works a lot with strings defined in C as:

struct vec_t {
char *base;
size_t len;
}

is there a easy way to feed regular D strings to functions that 
accept vec_t*

without creating a vec_t every time
or do i write wrappers for these functions and if so, what is the 
most elegant way

to build them?

so far i defined vec_t as:

struct vec_t {
char *base;
size_t len;

this(string s) { base = s.ptr; len = s.lenght; }

nothrow @nogc inout(char)[] toString() inout @property { return 
base[0 .. len]; }


nothrow @nogc @property const(char)[]  toSlice()
{
return cast(string)  base[0..len];
}
alias toString this;
}

but i guess there is a more elegant way?!


Small structs: interfacing with C++ potentially broken

2021-12-20 Thread Jan via Digitalmars-d-learn

I have a small struct that I'm trying to interface to.

C++
```cpp
struct __declspec(dllexport) SmallStruct
{
  float value = 0;
  //float value2 = 0;
  //float value3 = 0;

  SmallStruct(float val)
: value(val)
  {
  }

  static SmallStruct GetValue(float input)
  {
return SmallStruct(input * 3.141f);
  }
};
```

And on the D side:

```cpp
extern(C++) struct SmallStruct
{
  float value = 0;
//   float value2 = 0;
//   float value3 = 0;

  static SmallStruct GetValue(float input);
};
```

Then I use it like this:

```cpp
SmallStruct s = SmallStruct.GetValue(3);
```

Running this crashes on the C++ side, with an access violation 
writing data.
Looking at the disassembly, it seems that C++ expects the 
Smallstruct return object to be passed in, whereas D assumes that 
the SmallStruct is passed through registers.


This is with MVSC 2019 compiled for x64 and DMD v2.098.0.

If I enable 'value2' and 'value3', it seems that both compilers 
start to agree on the calling convention.


Is this a known issue, or is there a way to instruct DMD to use a 
specific calling convention for a given type?




Interfacing with c and platform dependent sizes

2011-02-25 Thread simendsjo

C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't 
exist in 64 bit?


Using a delegate when interfacing with C

2014-07-05 Thread Marco Cosentino via Digitalmars-d-learn

Hi,
I'm quite new to D and I'm not able to find out what I'm doing
wrong.

Consider the following code:

  class ClientImplementation {
   private ProcessDelegate processDelegate;

   void setProcessDelegate(ProcessDelegate deleg) {
 this.processDelegate = deleg;
 extern(C) ProcessCallback callback = function int(NFrames
nframes, void* data) {
   auto client = *(cast(ClientImplementation*) data);
   return client.processDelegate(nframes);
 };
 this.setProcessCallback(callback, cast(void *) &this);
   }

In my D wrapper for a C API I want to use delegates. The C API
accepts a callback which has a generic void* parameter which can
be specified when setting the callback (it will be stored and
passed in the callback when it gets called... a common pattern in
C APIs).
So I want to use it to make delegates possible.
The problem with this approach is that I get a segmentation fault
on the line:
auto client = *(cast(ClientImplementation*) data);
as soon as the callback is called the first time.
The callback is called in another thread (but this shouldn't be a
problem since ClientImplementation is a class and therefore
instances are created in the heap).

Can somebody help me in figuring out why this happens?

I also tried unsuccesfully
auto client = cast(ClientImplementation*) data;


Re: interfacing with C: strings and byte vectors

2016-06-11 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 11 June 2016 at 09:32:54 UTC, yawniek wrote:



so far i defined vec_t as:

struct vec_t {
char *base;
size_t len;

this(string s) { base = s.ptr; len = s.lenght; }

nothrow @nogc inout(char)[] toString() inout @property { return 
base[0 .. len]; }


nothrow @nogc @property const(char)[]  toSlice()
{
return cast(string)  base[0..len];
}
alias toString this;
}

but i guess there is a more elegant way?!


No, you've got the right idea with the constructor. You just need 
to change your implementation.


You have two big problems with your current constructor. First, 
only string literals in D (e.g. "foo") are guaranteed to be null 
terminated. If you construct a vec_t with a string that is not a 
literal, then you can have a problem on the C side where it is 
expected to be null terminated. Second, if the string you pass to 
the constructor was allocated on the GC heap and at some point is 
collected, then base member of the vec_t will point to an invalid 
memory location.


A simple approach would be:

this(string s)
{
import std.string : toStringz;
base = s.toStringz();
len = s.length;
}

Second, your toString and toSlice implementations are potentially 
problematic. Aside from the fact that toString is returning a 
slice and toSlice is returning a string, the slice you create 
there will always point to the same location as base. If base 
becomes invalid, then so will the slice.


For the toString impelementation, you really should be doing 
something like this:


string toString() nothrow inout {
import std.conv.to;
return to!string(base);
}

I don't know what benefit you are expecting from the toSlice 
method. If you absolutely need it, you should return implement it 
like so:


char[] toSlice() nothrow inout {
return base[0 .. len].dup;
}

This will give you a character array that is modifiable without 
worrying about the what happens to base. If you really want, you 
can declare the return as const(char)[].


Rather than toSlice, which isn't something the compiler is aware 
of, it would be much more appropriate to implement opSlice along 
with opDollar. Then it's possible to do this:


auto slice = myVec[0 .. $]. Of course, if you don't want to allow 
aribrary slices, then perhaps toSlice is better.




Re: interfacing with C: strings and byte vectors

2016-06-11 Thread yawniek via Digitalmars-d-learn

On Saturday, 11 June 2016 at 10:26:17 UTC, Mike Parker wrote:

On Saturday, 11 June 2016 at 09:32:54 UTC, yawniek wrote:



thanks mike for the in depth answer.
i forgot to add a few important points:
- the strings in vec_t are not c strings
- vec_t might contain other data than strings

the original ctor i pasted actually doesn't even work, temporarly 
i solved it like


this(string s) {
char[] si = cast(char[]) s; //i'm scared
base = si.ptr;
len = si.length;
}
is there a better solution than to fearlessly cast away 
immutability?
i guess i could just make a second vec_t that has immutable base 
and length

that can be used in D to stay clean, would that be worth anything?

now what i still don't have a proper idea for is how can i create 
wrappers for the

methods accepting vec_t in a clean way.
for the vec_t that are allocated in D-land we can state that the 
C libs will not modify the data.

there is a lot of functions that accept vec_t.
is there no way to have  strings auto cast to vec_t ?
another way i see is a UDA that generates the wrapper function(s).
other ideas?


Re: interfacing with C: strings and byte vectors

2016-06-11 Thread ag0aep6g via Digitalmars-d-learn

On 06/11/2016 01:59 PM, yawniek wrote:

i forgot to add a few important points:
- the strings in vec_t are not c strings
- vec_t might contain other data than strings

the original ctor i pasted actually doesn't even work, temporarly i
solved it like

 this(string s) {
 char[] si = cast(char[]) s; //i'm scared


Rightfully so. Casting away immutable shouldn't be done lightly.


 base = si.ptr;
 len = si.length;
 }
is there a better solution than to fearlessly cast away immutability?
i guess i could just make a second vec_t that has immutable base and length
that can be used in D to stay clean, would that be worth anything?


Sure. You wouldn't have to do the risky cast then.


now what i still don't have a proper idea for is how can i create
wrappers for the
methods accepting vec_t in a clean way.
for the vec_t that are allocated in D-land we can state that the C libs
will not modify the data.
there is a lot of functions that accept vec_t.
is there no way to have  strings auto cast to vec_t ?


I don't think so, no. You can make a new type and use alias this to have 
it convert implicitly to vec_t, but you can't enable that for string.


There is no feature to implicitly convert *from* another type, only *to* 
another type.



another way i see is a UDA that generates the wrapper function(s).
other ideas?


Generating the wrappers seems ok to me.

Regarding a UDA: I haven't really used them, but you'd still have to 
iterate over all functions that have the attribute, right? At that 
point, the UDA might be pointless. Can also iterate over everything and 
check if there's a vec_t parameter.


Re: Small structs: interfacing with C++ potentially broken

2021-12-20 Thread Tim via Digitalmars-d-learn

On Monday, 20 December 2021 at 10:24:00 UTC, Jan wrote:
Is this a known issue, or is there a way to instruct DMD to use 
a specific calling convention for a given type?


This looks like a bug. It seems to work without constructor in 
C++, but still crashes with a constructor in D. It also seems to 
work if a trivial destructor is added in D: ~this(){}


This could be related to POD types in C++. Structs with 
constructor or destructor are probably passed differently, but 
dmd only looks at the destructor.


Re: Small structs: interfacing with C++ potentially broken

2021-12-20 Thread Tejas via Digitalmars-d-learn

On Monday, 20 December 2021 at 11:58:03 UTC, Tim wrote:

On Monday, 20 December 2021 at 10:24:00 UTC, Jan wrote:
Is this a known issue, or is there a way to instruct DMD to 
use a specific calling convention for a given type?


This looks like a bug. It seems to work without constructor in 
C++, but still crashes with a constructor in D. It also seems 
to work if a trivial destructor is added in D: ~this(){}


This could be related to POD types in C++. Structs with 
constructor or destructor are probably passed differently, but 
dmd only looks at the destructor.


I think it's got something to do with 
[this](https://forum.dlang.org/post/capevemlbdanirtcj...@forum.dlang.org)


Re: Small structs: interfacing with C++ potentially broken

2021-12-20 Thread Jan via Digitalmars-d-learn

On Monday, 20 December 2021 at 11:58:03 UTC, Tim wrote:

On Monday, 20 December 2021 at 10:24:00 UTC, Jan wrote:
Is this a known issue, or is there a way to instruct DMD to 
use a specific calling convention for a given type?


This looks like a bug. It seems to work without constructor in 
C++, but still crashes with a constructor in D. It also seems 
to work if a trivial destructor is added in D: ~this(){}


This could be related to POD types in C++. Structs with 
constructor or destructor are probably passed differently, but 
dmd only looks at the destructor.


Well, that at least gives me a way to work around this issue.


Interfacing with C++ std::shared_ptr and std::unique_ptr

2020-06-09 Thread Andre Pany via Digitalmars-d-learn

Hi,

I would like to interface with the library 
https://github.com/NTNU-IHB/FMI4cpp

and have following class definitions in the header file:

``` c++
namespace fmi4cpp {

template
class fmu_base {

public:

const std::string guid() const {
return get_model_description()->guid;
}

const std::string model_name() const {
return get_model_description()->model_name;
}

virtual std::shared_ptr 
get_model_description() const = 0;


};

template
class fmu_provider : public virtual 
fmu_base {


public:

virtual bool supports_cs() const = 0;

virtual bool supports_me() const = 0;

virtual std::unique_ptr  as_cs_fmu() const = 0;

virtual std::unique_ptr  as_me_fmu() const = 0;

};
```

While unique_ptr is already available in drunime library 
core.stdcpp.memory,
shared_ptr is missing. Does someone already have translated 
shared_ptr?


Also, the C++ classes make use of templates. Is it still possible 
to call these

classes from D?

Kind regards
Andre


Re: Interfacing with c and platform dependent sizes

2011-02-25 Thread bearophile
simendsjo:

> So.. A long in C is the same as the platform size? And long long doesn't 
> exist in 64 bit?

In D the size of int/uint is 32 bits and long/ulong is 64 bits.

In C the size of int, unsigned int, long, long long int, unsigned long long 
int, etc are not fixed, the change according to the CPU. sizeof(int) <= 
sizeof(long) <= sizeof(long long).

A help:
http://www.digitalmars.com/d/2.0/phobos/std_stdint.html

Bye,
bearophile


Re: Interfacing with c and platform dependent sizes

2011-02-25 Thread simendsjo

On 26.02.2011 02:06, bearophile wrote:

simendsjo:


So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In D the size of int/uint is 32 bits and long/ulong is 64 bits.

In C the size of int, unsigned int, long, long long int, unsigned long long int, etc 
are not fixed, the change according to the CPU. sizeof(int)<= sizeof(long)<= 
sizeof(long long).

A help:
http://www.digitalmars.com/d/2.0/phobos/std_stdint.html

Bye,
bearophile


Ouch.. Any tips on porting C code that would work nicely with a 
transition to 64 bit?

Should I change all long and int to int_atleast_32_t and long long to 64?


Re: Interfacing with c and platform dependent sizes

2011-02-25 Thread Jonathan M Davis
On Friday, February 25, 2011 17:16:31 simendsjo wrote:
> On 26.02.2011 02:06, bearophile wrote:
> > simendsjo:
> >> So.. A long in C is the same as the platform size? And long long doesn't
> >> exist in 64 bit?
> > 
> > In D the size of int/uint is 32 bits and long/ulong is 64 bits.
> > 
> > In C the size of int, unsigned int, long, long long int, unsigned long
> > long int, etc are not fixed, the change according to the CPU.
> > sizeof(int)<= sizeof(long)<= sizeof(long long).
> > 
> > A help:
> > http://www.digitalmars.com/d/2.0/phobos/std_stdint.html
> > 
> > Bye,
> > bearophile
> 
> Ouch.. Any tips on porting C code that would work nicely with a
> transition to 64 bit?
> Should I change all long and int to int_atleast_32_t and long long to 64?

It depends entirely on what the code is doing. It could be completely safe to 
convert all ints, longs, and long longs to long to long. Or you may have to 
choose int or long depending on what system the code is supposed to be for.

In many cases, using a larger type wouldn't matter, since it can hold more than 
the smaller type, so whether the type in C/C++ was 32 bits or 64 bits is 
irrelevant. In other cases, the type needs to be an exact size, because the 
code 
is doing bit shifts or whatnot (in which case they _should_ have been using 
int32_t and int64_t on Linux and whatever the equivalent is on Windows, but 
unfortunately, many programmers don't). And if you're dealing with a struct, 
it's possible that that struct has to be an exact size (e.g. for some binary 
format), and using the wrong type in converting could make it the wrong size.

If you want to know what the appropriate D type is for the C/C++ code, you 
_need_ to know what it does.  Now, IIRC, int is almost guaranteed to be 32 bits 
at this point, and long long is essentially guaranteed to be 64 bits, but long 
varies from system to system - both in terms of OS and architecture. IIRC, long 
is 32 bits on Solaris and Windows - both on x86 and x86_64 - but it's 32 bits 
in 
x86 Linux and 64 bits in x86_64 Linux. So, if all the code uses is int and long 
long, then it's probably reasonably safe to use int for int and long for long 
long, but it's ultimately system dependent. Personally, I would argue that 
C/C++ 
code should use int when you don't care about the size of an integral type and 
use the intX_t types (where X is 8, 16, 32, or 64) when you _do_ care about the 
size, but there's no guarantee that programmers are going to be that 
disciplined 
about it.

In any case, if you really don't know the code and don't want to take the time 
to understand it, I'd use int for int, long for long long, and then if they 
have 
long, I'd do the research to figure out which OS and architecture the code is 
supposed to be for and use int if long long is 32 bits and long if it's 64 
bits. 
If you don't know what system it was built for, then I'd probably just use long 
and hoped that they weren't doing anything that made using an integral type 
which was too large a problem.

- Jonathan M Davis


Re: Interfacing with c and platform dependent sizes

2011-02-25 Thread Steven Schveighoffer
On Fri, 25 Feb 2011 20:06:04 -0500, bearophile   
wrote:



simendsjo:


So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In D the size of int/uint is 32 bits and long/ulong is 64 bits.

In C the size of int, unsigned int, long, long long int, unsigned long  
long int, etc are not fixed, the change according to the CPU.  
sizeof(int) <= sizeof(long) <= sizeof(long long).


It's *recommended* that ints be the size of a standard register.  So,  
those sizes do not have to follow the CPU architecture, and compilers  
could potentially use different sizes even on the same platform.


D (and most languages that came after C) did a much better job on this.

BTW, I think long long is a gnu extension, it's not standard C (I don't  
think long long exists in Visual C for instance).


-Steve


Re: Interfacing with c and platform dependent sizes

2011-02-25 Thread Jonathan M Davis
On Friday, February 25, 2011 17:35:02 Jonathan M Davis wrote:
> On Friday, February 25, 2011 17:16:31 simendsjo wrote:
> > On 26.02.2011 02:06, bearophile wrote:
> > > simendsjo:
> > >> So.. A long in C is the same as the platform size? And long long
> > >> doesn't exist in 64 bit?
> > > 
> > > In D the size of int/uint is 32 bits and long/ulong is 64 bits.
> > > 
> > > In C the size of int, unsigned int, long, long long int, unsigned long
> > > long int, etc are not fixed, the change according to the CPU.
> > > sizeof(int)<= sizeof(long)<= sizeof(long long).
> > > 
> > > A help:
> > > http://www.digitalmars.com/d/2.0/phobos/std_stdint.html
> > > 
> > > Bye,
> > > bearophile
> > 
> > Ouch.. Any tips on porting C code that would work nicely with a
> > transition to 64 bit?
> > Should I change all long and int to int_atleast_32_t and long long to 64?
> 
> It depends entirely on what the code is doing. It could be completely safe
> to convert all ints, longs, and long longs to long to long. Or you may
> have to choose int or long depending on what system the code is supposed
> to be for.
> 
> In many cases, using a larger type wouldn't matter, since it can hold more
> than the smaller type, so whether the type in C/C++ was 32 bits or 64 bits
> is irrelevant. In other cases, the type needs to be an exact size, because
> the code is doing bit shifts or whatnot (in which case they _should_ have
> been using int32_t and int64_t on Linux and whatever the equivalent is on
> Windows, but unfortunately, many programmers don't). And if you're dealing
> with a struct, it's possible that that struct has to be an exact size
> (e.g. for some binary format), and using the wrong type in converting
> could make it the wrong size.
> 
> If you want to know what the appropriate D type is for the C/C++ code, you
> _need_ to know what it does.  Now, IIRC, int is almost guaranteed to be 32
> bits at this point, and long long is essentially guaranteed to be 64 bits,
> but long varies from system to system - both in terms of OS and
> architecture. IIRC, long is 32 bits on Solaris and Windows - both on x86
> and x86_64 - but it's 32 bits in x86 Linux and 64 bits in x86_64 Linux.
> So, if all the code uses is int and long long, then it's probably
> reasonably safe to use int for int and long for long long, but it's
> ultimately system dependent. Personally, I would argue that C/C++ code
> should use int when you don't care about the size of an integral type and
> use the intX_t types (where X is 8, 16, 32, or 64) when you _do_ care
> about the size, but there's no guarantee that programmers are going to be
> that disciplined about it.
> 
> In any case, if you really don't know the code and don't want to take the
> time to understand it, I'd use int for int, long for long long, and then
> if they have long, I'd do the research to figure out which OS and
> architecture the code is supposed to be for and use int if long long is 32
> bits and long if it's 64 bits. If you don't know what system it was built
> for, then I'd probably just use long and hoped that they weren't doing
> anything that made using an integral type which was too large a problem.

Actually, I just realized that I was thinking in terms of porting C++ code to 
D. 
You're going to have to be more strict if you're just converting header files. 
However, what you can do is just compile something like this in C/C++ on your 
system:

printf("int -> %d bytes", sizeof(int));
printf("long -> %d bytes", sizeof(long));
printf("long long -> %d bytes", sizeof(long long));

Then you'll know what they are on your system, and you can convert them over 
just fine. You just have to remember to do the same on any other system that 
you 
compile your code on. Bleh. At least D went the route of standarizing the size 
of its primitive types.

- Jonathan M Davis


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Jacob Carlborg

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In general you can follow the table at 
http://www.digitalmars.com/d/2.0/htomodule.html


But when it comes to "long" in C you have to be careful. On 32bit 
platforms a C "long" will be 32bit long. But on 64bit platforms it 
depends of what data model is used. To simplify things:


* On Windows 64bit a C "long" will be 32bit long
* On Posix 64bit a C "long" will be 64bit long.

What you can do is to create an alias called "c_long" and "c_ulong", 
something like this:


version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models: 
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models


--
/Jacob Carlborg


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Jacob Carlborg

On 2011-02-26 02:35, Jonathan M Davis wrote:

On Friday, February 25, 2011 17:16:31 simendsjo wrote:

On 26.02.2011 02:06, bearophile wrote:

simendsjo:

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In D the size of int/uint is 32 bits and long/ulong is 64 bits.

In C the size of int, unsigned int, long, long long int, unsigned long
long int, etc are not fixed, the change according to the CPU.
sizeof(int)<= sizeof(long)<= sizeof(long long).

A help:
http://www.digitalmars.com/d/2.0/phobos/std_stdint.html

Bye,
bearophile


Ouch.. Any tips on porting C code that would work nicely with a
transition to 64 bit?
Should I change all long and int to int_atleast_32_t and long long to 64?


It depends entirely on what the code is doing. It could be completely safe to
convert all ints, longs, and long longs to long to long. Or you may have to
choose int or long depending on what system the code is supposed to be for.

In many cases, using a larger type wouldn't matter, since it can hold more than
the smaller type, so whether the type in C/C++ was 32 bits or 64 bits is
irrelevant. In other cases, the type needs to be an exact size, because the code
is doing bit shifts or whatnot (in which case they _should_ have been using
int32_t and int64_t on Linux and whatever the equivalent is on Windows, but
unfortunately, many programmers don't). And if you're dealing with a struct,
it's possible that that struct has to be an exact size (e.g. for some binary
format), and using the wrong type in converting could make it the wrong size.

If you want to know what the appropriate D type is for the C/C++ code, you
_need_ to know what it does.  Now, IIRC, int is almost guaranteed to be 32 bits
at this point, and long long is essentially guaranteed to be 64 bits, but long
varies from system to system - both in terms of OS and architecture. IIRC, long
is 32 bits on Solaris and Windows - both on x86 and x86_64 - but it's 32 bits in
x86 Linux and 64 bits in x86_64 Linux. So, if all the code uses is int and long
long, then it's probably reasonably safe to use int for int and long for long
long, but it's ultimately system dependent. Personally, I would argue that C/C++
code should use int when you don't care about the size of an integral type and
use the intX_t types (where X is 8, 16, 32, or 64) when you _do_ care about the
size, but there's no guarantee that programmers are going to be that disciplined
about it.


A C "long" is 64bit long on Solaris 64bit according to this: 
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



In any case, if you really don't know the code and don't want to take the time
to understand it, I'd use int for int, long for long long, and then if they have
long, I'd do the research to figure out which OS and architecture the code is
supposed to be for and use int if long long is 32 bits and long if it's 64 bits.
If you don't know what system it was built for, then I'd probably just use long
and hoped that they weren't doing anything that made using an integral type
which was too large a problem.

- Jonathan M Davis



--
/Jacob Carlborg


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Jonathan M Davis
On Saturday 26 February 2011 02:51:08 Jacob Carlborg wrote:
> On 2011-02-26 02:35, Jonathan M Davis wrote:
> > On Friday, February 25, 2011 17:16:31 simendsjo wrote:
> >> On 26.02.2011 02:06, bearophile wrote:
> >>> simendsjo:
>  So.. A long in C is the same as the platform size? And long long
>  doesn't exist in 64 bit?
> >>> 
> >>> In D the size of int/uint is 32 bits and long/ulong is 64 bits.
> >>> 
> >>> In C the size of int, unsigned int, long, long long int, unsigned long
> >>> long int, etc are not fixed, the change according to the CPU.
> >>> sizeof(int)<= sizeof(long)<= sizeof(long long).
> >>> 
> >>> A help:
> >>> http://www.digitalmars.com/d/2.0/phobos/std_stdint.html
> >>> 
> >>> Bye,
> >>> bearophile
> >> 
> >> Ouch.. Any tips on porting C code that would work nicely with a
> >> transition to 64 bit?
> >> Should I change all long and int to int_atleast_32_t and long long to
> >> 64?
> > 
> > It depends entirely on what the code is doing. It could be completely
> > safe to convert all ints, longs, and long longs to long to long. Or you
> > may have to choose int or long depending on what system the code is
> > supposed to be for.
> > 
> > In many cases, using a larger type wouldn't matter, since it can hold
> > more than the smaller type, so whether the type in C/C++ was 32 bits or
> > 64 bits is irrelevant. In other cases, the type needs to be an exact
> > size, because the code is doing bit shifts or whatnot (in which case
> > they _should_ have been using int32_t and int64_t on Linux and whatever
> > the equivalent is on Windows, but unfortunately, many programmers
> > don't). And if you're dealing with a struct, it's possible that that
> > struct has to be an exact size (e.g. for some binary format), and using
> > the wrong type in converting could make it the wrong size.
> > 
> > If you want to know what the appropriate D type is for the C/C++ code,
> > you _need_ to know what it does.  Now, IIRC, int is almost guaranteed to
> > be 32 bits at this point, and long long is essentially guaranteed to be
> > 64 bits, but long varies from system to system - both in terms of OS and
> > architecture. IIRC, long is 32 bits on Solaris and Windows - both on x86
> > and x86_64 - but it's 32 bits in x86 Linux and 64 bits in x86_64 Linux.
> > So, if all the code uses is int and long long, then it's probably
> > reasonably safe to use int for int and long for long long, but it's
> > ultimately system dependent. Personally, I would argue that C/C++ code
> > should use int when you don't care about the size of an integral type
> > and use the intX_t types (where X is 8, 16, 32, or 64) when you _do_
> > care about the size, but there's no guarantee that programmers are going
> > to be that disciplined about it.
> 
> A C "long" is 64bit long on Solaris 64bit according to this:
> http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

Well, I've run into problems before due the size of long differing on Linux and 
Solaris and I thought that it was 64-bit Linux and 64-bit Solaris, but maybe it 
was actually 32-bit Solaris (I _know_ that it was 64-bit Linux though). 
Regardless, it just goes to show how careful you have to be when dealing with 
long in C and C++.

- Jonathan M Davis


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Mike Wey

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to "long" in C you have to be careful. On 32bit
platforms a C "long" will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C "long" will be 32bit long
* On Posix 64bit a C "long" will be 64bit long.

What you can do is to create an alias called "c_long" and "c_ulong",
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and c_ulong.

--
Mike Wey


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread simendsjo

On 26.02.2011 17:06, Mike Wey wrote:

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to "long" in C you have to be careful. On 32bit
platforms a C "long" will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C "long" will be 32bit long
* On Posix 64bit a C "long" will be 64bit long.

What you can do is to create an alias called "c_long" and "c_ulong",
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and c_ulong.


Thanks for all the answers. Is something like this correct?

version(X86_64)
{
version(Windows)
{
version = LLP64;
}
else version(Posix)
{
version = LP64;
}
else
{
static assert(0);
}

version(LLP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(LP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(ILP64)
{
alias short c_short;
alias ushort c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(SILP64)
{
alias long c_short;
alias ulong c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else
{
static assert(0);
}
}
else version(X86)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias uint c_size_t;
}
else
{
static assert(0);
}



Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Mike Wey

On 02/26/2011 05:58 PM, simendsjo wrote:

On 26.02.2011 17:06, Mike Wey wrote:

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some
code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long
doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to "long" in C you have to be careful. On 32bit
platforms a C "long" will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C "long" will be 32bit long
* On Posix 64bit a C "long" will be 64bit long.

What you can do is to create an alias called "c_long" and "c_ulong",
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and
c_ulong.


Thanks for all the answers. Is something like this correct?

version(X86_64)
{
version(Windows)
{
version = LLP64;
}
else version(Posix)
{
version = LP64;
}
else
{
static assert(0);
}

version(LLP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(LP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(ILP64)
{
alias short c_short;
alias ushort c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(SILP64)
{
alias long c_short;
alias ulong c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else
{
static assert(0);
}
}
else version(X86)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias uint c_size_t;
}
else
{
static assert(0);
}



The aliases look correct, but i don't think you'll need ILP64 or SILP64 
any time soon.


--
Mike Wey


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Bekenn

On 2/25/2011 7:24 PM, Steven Schveighoffer wrote:

BTW, I think long long is a gnu extension, it's not standard C (I don't
think long long exists in Visual C for instance).


I'm pretty sure it's standard as of C99 (though not yet for C++; that's 
coming with C++0x).  MSVC does indeed support it.


Re: Interfacing with c and platform dependent sizes

2011-02-27 Thread Jacob Carlborg

On 2011-02-26 17:06, Mike Wey wrote:

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to "long" in C you have to be careful. On 32bit
platforms a C "long" will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C "long" will be 32bit long
* On Posix 64bit a C "long" will be 64bit long.

What you can do is to create an alias called "c_long" and "c_ulong",
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and c_ulong.


Yeah, I always forgets that module in druntime, even though it's based 
on Tango where I do remember it.


--
/Jacob Carlborg


Re: Interfacing with c and platform dependent sizes

2011-02-27 Thread Jacob Carlborg

On 2011-02-26 23:02, Mike Wey wrote:

On 02/26/2011 05:58 PM, simendsjo wrote:

On 26.02.2011 17:06, Mike Wey wrote:

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some
code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long
doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to "long" in C you have to be careful. On 32bit
platforms a C "long" will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C "long" will be 32bit long
* On Posix 64bit a C "long" will be 64bit long.

What you can do is to create an alias called "c_long" and "c_ulong",
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and
c_ulong.


Thanks for all the answers. Is something like this correct?

version(X86_64)
{
version(Windows)
{
version = LLP64;
}
else version(Posix)
{
version = LP64;
}
else
{
static assert(0);
}

version(LLP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(LP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(ILP64)
{
alias short c_short;
alias ushort c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(SILP64)
{
alias long c_short;
alias ulong c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else
{
static assert(0);
}
}
else version(X86)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias uint c_size_t;
}
else
{
static assert(0);
}



The aliases look correct, but i don't think you'll need ILP64 or SILP64
any time soon.


I agree.

--
/Jacob Carlborg


Re: Interfacing with c and platform dependent sizes

2011-02-27 Thread Jacob Carlborg

On 2011-02-26 17:58, simendsjo wrote:

On 26.02.2011 17:06, Mike Wey wrote:

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some
code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long
doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to "long" in C you have to be careful. On 32bit
platforms a C "long" will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C "long" will be 32bit long
* On Posix 64bit a C "long" will be 64bit long.

What you can do is to create an alias called "c_long" and "c_ulong",
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and
c_ulong.


Thanks for all the answers. Is something like this correct?

version(X86_64)
{
version(Windows)
{
version = LLP64;
}
else version(Posix)
{
version = LP64;
}
else
{
static assert(0);
}

version(LLP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(LP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(ILP64)
{
alias short c_short;
alias ushort c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(SILP64)
{
alias long c_short;
alias ulong c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else
{
static assert(0);
}
}
else version(X86)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias uint c_size_t;
}
else
{
static assert(0);
}



I suggest you use core.stdc.config instead, I forgot it existed. BTW 
size_t already exists in D (defined in the object module) and it will be 
the same as size_t in C.


--
/Jacob Carlborg


Re: Interfacing with c and platform dependent sizes

2011-02-27 Thread Steven Schveighoffer

On Sat, 26 Feb 2011 22:24:52 -0500, Bekenn  wrote:


On 2/25/2011 7:24 PM, Steven Schveighoffer wrote:

BTW, I think long long is a gnu extension, it's not standard C (I don't
think long long exists in Visual C for instance).


I'm pretty sure it's standard as of C99 (though not yet for C++; that's  
coming with C++0x).  MSVC does indeed support it.


OK, I was not aware, my C book is from college, and I went to college in  
94.


I always thought in Windows you had to use something like __int64.

-Steve


Re: Interfacing with c and platform dependent sizes

2011-02-27 Thread simendsjo

On 27.02.2011 11:43, Jacob Carlborg wrote:

On 2011-02-26 17:58, simendsjo wrote:

On 26.02.2011 17:06, Mike Wey wrote:

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some
code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long
doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to "long" in C you have to be careful. On 32bit
platforms a C "long" will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C "long" will be 32bit long
* On Posix 64bit a C "long" will be 64bit long.

What you can do is to create an alias called "c_long" and "c_ulong",
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and
c_ulong.


Thanks for all the answers. Is something like this correct?

version(X86_64)
{
version(Windows)
{
version = LLP64;
}
else version(Posix)
{
version = LP64;
}
else
{
static assert(0);
}

version(LLP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(LP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(ILP64)
{
alias short c_short;
alias ushort c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(SILP64)
{
alias long c_short;
alias ulong c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else
{
static assert(0);
}
}
else version(X86)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias uint c_size_t;
}
else
{
static assert(0);
}



I suggest you use core.stdc.config instead, I forgot it existed. BTW
size_t already exists in D (defined in the object module) and it will be
the same as size_t in C.



Ok. Thanks.


Re: Interfacing with c and platform dependent sizes

2011-02-27 Thread Jonathan M Davis
On Sunday 27 February 2011 05:41:49 Steven Schveighoffer wrote:
> On Sat, 26 Feb 2011 22:24:52 -0500, Bekenn  wrote:
> > On 2/25/2011 7:24 PM, Steven Schveighoffer wrote:
> >> BTW, I think long long is a gnu extension, it's not standard C (I don't
> >> think long long exists in Visual C for instance).
> > 
> > I'm pretty sure it's standard as of C99 (though not yet for C++; that's
> > coming with C++0x).  MSVC does indeed support it.
> 
> OK, I was not aware, my C book is from college, and I went to college in
> 94.
> 
> I always thought in Windows you had to use something like __int64.

That would be the smart thing to do, but long long does exist. IHMO, if you 
don't care about the size of an integral type in C/C++, you use int. Otherwise, 
you use a type that specifices it's size and is _guaranteed_ to be that size on 
all systems. Using types like long and long long is just asking for it. 
Fortunately, D specifies the size of its types, so that isn't a problem.

- Jonathan M Davis


Re: Using a delegate when interfacing with C

2014-07-05 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 5 July 2014 at 22:18:56 UTC, Marco Cosentino wrote:

   auto client = *(cast(ClientImplementation*) data);


Try just

auto client = cast(ClientImplementation) data;


and

 this.setProcessCallback(callback, cast(void *) &this);

setProcessCallback(callback, cast(void*) this);


Can somebody help me in figuring out why this happens?



The reason is a class this in D is already a pointer (just a 
hidden one) so when you do &this in a class, it is like a 
ClientImplementation** in C - a pointer to a (temporary) pointer. 
So by the time the callback runs, it is pointing to nonsense.


In general, remember any class reference in D is already 
equivalent to a pointer in C or C++ and can be casted straight to 
void* without needing to take its address.


Re: Using a delegate when interfacing with C

2014-07-05 Thread Marco Cosentino via Digitalmars-d-learn

On Saturday, 5 July 2014 at 22:28:48 UTC, Adam D. Ruppe wrote:

In general, remember any class reference in D is already 
equivalent to a pointer in C or C++ and can be casted straight 
to void* without needing to take its address.


Thanks Adam,
you're a life saver ;). It works like a charme.


Re: Using a delegate when interfacing with C

2014-07-06 Thread Marco Cosentino via Digitalmars-d-learn

Hey Adam,
an interesting aspect of what I'd like to achieve is to use
compile-time reflection to generate the wrapper functions for all
the delegates (there are ~ 10).

The pattern is like what I presented eariler and in addition to
that there are some delegates which have no return type (void).

I managed to write a template like this (D is awesome):

alias ProcessDelegate = int delegate(NFrames nframes);

import std.traits;
private  template CallbackWrapper(alias T) if(isDelegate!T) {
   extern(C) static auto wrapper(ParameterTypeTuple!T params, void
* data) {
 auto client = cast(ClientImplementation) data;
 return mixin("client." ~ __traits(identifier, T) ~
"(params)");
   }
}

   void setProcessDelegate(ProcessDelegate deleg) {
 processDelegate = deleg;
 setProcessCallback( &
CallbackWrapper!(processDelegate).wrapper, cast(void *) this);
   }


How to use inheritance when interfacing with C++ classes?

2021-12-09 Thread rempas via Digitalmars-d-learn
I would like to interface with a C++ library called 
[FLTK](https://www.fltk.org/). I'm trying to implement the 
binding for the classes based to what I've read 
[here](https://dlang.org/spec/cpp_interface.html#classes) but it 
seems that It doesn't work as expected for me. I want to 
implement the "abstract" class "Fl_Widget" and the class 
"Fl_Group" which inherits from the "Fl_Widget". I will put a part 
of the code as there is no reason to put the whole code and make 
the post unnecessarily big. If in any case however, you need the 
whole reference: 
[Fl_Widget](https://fltk.gitlab.io/fltk/classFl__Widget.html) and 
[Fl_Group](https://fltk.gitlab.io/fltk/classFl__Group.html). Here 
is the code:


```
extern(C++) {
  abstract class Fl_Widget {
void   _clear_fullscreen();
void   _set_fullscreen();
  }

  class Fl_Group : Fl_Widget {
ref Fl_Widget*_ddfdesign_kludge();
void  add(ref Fl_Widget);
void  add(Fl_Widget*o);
  }
}
```

Normally this should work but the "Fl_Group" class makes in bug 
and I'm getting the following error message:


```
Linking...
/usr/bin/ld: 
.dub/build/application-debug-linux.posix-x86_64-dmd_v2.098.0-A4E26D206D34B9B9CA1A0366B3CE0F2C/dfltk.o:(.data._D4test8Fl_Group6__vtblZ+0x0): undefined reference to `Fl_Widget::_clear_fullscreen()'
/usr/bin/ld: 
.dub/build/application-debug-linux.posix-x86_64-dmd_v2.098.0-A4E26D206D34B9B9CA1A0366B3CE0F2C/dfltk.o:(.data._D4test8Fl_Group6__vtblZ+0x8): undefined reference to `Fl_Widget::_set_fullscreen()'
/usr/bin/ld: 
.dub/build/application-debug-linux.posix-x86_64-dmd_v2.098.0-A4E26D206D34B9B9CA1A0366B3CE0F2C/dfltk.o:(.data._D4test8Fl_Group6__vtblZ+0x10): undefined reference to `Fl_Group::_ddfdesign_kludge()'
/usr/bin/ld: 
.dub/build/application-debug-linux.posix-x86_64-dmd_v2.098.0-A4E26D206D34B9B9CA1A0366B3CE0F2C/dfltk.o:(.data._D4test8Fl_Group6__vtblZ+0x18): undefined reference to `Fl_Group::add(Fl_Widget*&)'
/usr/bin/ld: 
.dub/build/application-debug-linux.posix-x86_64-dmd_v2.098.0-A4E26D206D34B9B9CA1A0366B3CE0F2C/dfltk.o:(.data._D4test8Fl_Group6__vtblZ+0x20): undefined reference to `Fl_Group::add(Fl_Widget**)'

collect2: error: ld returned 1 exit status
Error: linker exited with status 1
```

Anyone has an idea?


Re: Interfacing with C++ std::shared_ptr and std::unique_ptr

2020-06-09 Thread evilrat via Digitalmars-d-learn

On Wednesday, 10 June 2020 at 06:43:24 UTC, Andre Pany wrote:


Also, the C++ classes make use of templates. Is it still 
possible to call these

classes from D?


It should be, I did something similar and it worked. But it was 
quite some time ago so I don't remember exact situation and any 
details.


However you still be out of luck if the types you are trying to 
use is present in header only, since there is simply nothing to 
link with, so now you have to port whole template to D, or make 
dummy wrapper in C++ that forces the compiler to emit those 
symbols.


Same with ctor/dtors, if you have a class that is only used in 
some executable and not present in any of a .lib/.a form you're 
stuck. This is especially annoying with destructors because it 
renders the whole thing unusable without helper libraries that 
does new/delete in order to get the damn symbols emitted in 
object files to be able to link.


Re: Interfacing with C++ std::shared_ptr and std::unique_ptr

2020-06-10 Thread Mathias LANG via Digitalmars-d-learn

On Wednesday, 10 June 2020 at 06:43:24 UTC, Andre Pany wrote:

Hi,

I would like to interface with the library 
https://github.com/NTNU-IHB/FMI4cpp

and have following class definitions in the header file:

``` c++
namespace fmi4cpp {

template
class fmu_base {

public:

const std::string guid() const {
return get_model_description()->guid;
}

const std::string model_name() const {
return get_model_description()->model_name;
}

virtual std::shared_ptr 
get_model_description() const = 0;


};

templateme_fmu>
class fmu_provider : public virtual 
fmu_base {


public:

virtual bool supports_cs() const = 0;

virtual bool supports_me() const = 0;

virtual std::unique_ptr  as_cs_fmu() const = 0;

virtual std::unique_ptr  as_me_fmu() const = 0;

};
```

While unique_ptr is already available in drunime library 
core.stdcpp.memory,
shared_ptr is missing. Does someone already have translated 
shared_ptr?


Also, the C++ classes make use of templates. Is it still 
possible to call these

classes from D?

Kind regards
Andre


Depending on your needs, it might be trivial. We use this, and it 
works accross all 3 platforms: 
https://github.com/bpfkorea/agora/blob/ddd65e2fc3975d9c14ad36bcf28e5cd32de08945/source/scpd/Cpp.d#L38-L64


As mentioned, you will need to have the instantiation done on the 
C++ side, but that's true for any template. Feel free to ask on 
slack #cpp-interop.


Re: Interfacing with C++ std::shared_ptr and std::unique_ptr

2020-06-10 Thread Andre Pany via Digitalmars-d-learn

On Wednesday, 10 June 2020 at 08:31:47 UTC, Mathias LANG wrote:

On Wednesday, 10 June 2020 at 06:43:24 UTC, Andre Pany wrote:

[...]


Depending on your needs, it might be trivial. We use this, and 
it works accross all 3 platforms: 
https://github.com/bpfkorea/agora/blob/ddd65e2fc3975d9c14ad36bcf28e5cd32de08945/source/scpd/Cpp.d#L38-L64


As mentioned, you will need to have the instantiation done on 
the C++ side, but that's true for any template. Feel free to 
ask on slack #cpp-interop.


Thanks for all the answers. I will have a look.

Kind regards
Andre


Re: How to use inheritance when interfacing with C++ classes?

2021-12-09 Thread Tim via Digitalmars-d-learn

On Thursday, 9 December 2021 at 19:05:08 UTC, rempas wrote:

Anyone has an idea?


The referenced methods like Fl_Widget::_clear_fullscreen are 
implemented directly in the header, so the D code also needs the 
implementation, because it is not included in the compiled 
library.


Methods, which are not virtual in C++, also have to be marked 
final in D, because C++ and D use a different default.


Re: How to use inheritance when interfacing with C++ classes?

2021-12-10 Thread rempas via Digitalmars-d-learn

On Thursday, 9 December 2021 at 21:35:14 UTC, Tim wrote:


The referenced methods like Fl_Widget::_clear_fullscreen are 
implemented directly in the header, so the D code also needs 
the implementation, because it is not included in the compiled 
library.


What is funny about that is that I looked an the official class 
reference and copy pasted the code from here but I also looked at 
the header files and saw what you said but for some reason it 
completely slipped from my head...


Methods, which are not virtual in C++, also have to be marked 
final in D, because C++ and D use a different default.


Is this a must or just good practices?




Re: How to use inheritance when interfacing with C++ classes?

2021-12-10 Thread Tim via Digitalmars-d-learn

On Friday, 10 December 2021 at 12:46:07 UTC, rempas wrote:

On Thursday, 9 December 2021 at 21:35:14 UTC, Tim wrote:
Methods, which are not virtual in C++, also have to be marked 
final in D, because C++ and D use a different default.


Is this a must or just good practices?


All virtual methods have to match exactly including order. If a 
virtual method is missing or added, then calling this or a later 
virtual method could call the wrong method or generate a 
segmentation fault. Non-virtual methods have to be marked final 
in D, but can also be removed.


Re: How to use inheritance when interfacing with C++ classes?

2021-12-10 Thread rempas via Digitalmars-d-learn

On Friday, 10 December 2021 at 16:42:33 UTC, Tim wrote:


All virtual methods have to match exactly including order. If a 
virtual method is missing or added, then calling this or a 
later virtual method could call the wrong method or generate a 
segmentation fault. Non-virtual methods have to be marked final 
in D, but can also be removed.


Great info! I'll have everything in mind! Thanks a lot and have 
an amazing day!!!


Interfacing with C - calling member function of D struct from C?

2017-06-24 Thread unleashy via Digitalmars-d-learn

Hello! If I have a D struct like:

struct Foo
{
int bar;

void addToBar(int what) {
bar += what;
}
}

How would I call `addToBar` from C code? Would I need to put the 
`addToBar` function outside of the struct and mark it as `extern 
(C)` and in normal D code take advantage of UFCS or is there some 
magic C incantation?


I've scoured the forums and other places for anything about this 
but couldn't find any information whatsoever... so yeah. (or my 
Google-fu is terrible)


Thanks!


Re: Interfacing with C - calling member function of D struct from C?

2017-06-24 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 25 June 2017 at 02:05:35 UTC, unleashy wrote:

How would I call `addToBar` from C code?


You don't. Instead write it like:

struct Foo
{
int bar;
}

extern(C) void addToBar(Foo* foo, int what) {
   foo.bar += what;
}


Then define it in C the same way and you call it the normal way 
from C.


But from D, you can UFCS call it:

Foo* foo = new Foo();
foo.addToBar(5); // cool


though I'd prolly just call it from D the same way you do from C 
too.


Re: Interfacing with C - calling member function of D struct from C?

2017-06-25 Thread unleashy via Digitalmars-d-learn

On Sunday, 25 June 2017 at 02:09:53 UTC, Adam D. Ruppe wrote:

On Sunday, 25 June 2017 at 02:05:35 UTC, unleashy wrote:

How would I call `addToBar` from C code?


You don't. Instead write it like:

struct Foo
{
int bar;
}

extern(C) void addToBar(Foo* foo, int what) {
   foo.bar += what;
}


Then define it in C the same way and you call it the normal way 
from C.


But from D, you can UFCS call it:

Foo* foo = new Foo();
foo.addToBar(5); // cool


though I'd prolly just call it from D the same way you do from 
C too.


Thank you, this is what I suspected :)


how to handle memory ownership when interfacing with C/C++ via internal pointers

2013-10-10 Thread Timothee Cour
Short version:
I have a struct A* aptr allocated in C/C++ with an internal
pointer aptr->ptr (say a double*)
I want to store a reference x (say double[]) in D to aptr only through
aptr->ptr, not through aptr directly as it's inconvenient in my use case.

How do I achieve that, so that when x goes out of scope, some deallocator
for aptr will be called ?

Long version:

suppose I have C++ code:
struct A{
  double*ptr;
  A(size_t n){ptr=(double*)malloc(n);}
  ~A(){free(ptr);}
};

and a D wrapper around it:
extern(C){struct A; A*A_new(size_t n); void A_delete(A*a);
double*A_ptr(A*a);}

I want to use it as follows:

double[] get_x(size_t n){
 return A_new(n).A_ptr[0..n];
}

void main(){
  double[]x=get_x(n);
// do something with x;
}


It's trivial to handle this via a class wrapper:
class A2{
A*a;
this(size_t n){a=A_new(n);}
~this(){A_delete(n);}
double*ptr(){return A_ptr(a);}
}
double[] get_x(size_t n){
 auto a2=new A2(n);
 return a2.ptr;
//this doesn't help much though, A2 will go out of scope when this function
exits.
}


but I don't want to maintain objects of class A2 around, just double[]
slices as above.

Is there some magic involving core.memory.addRoot,addRange (etc) I can use
so that a2 stays alive as long as x stays alive? (in which case when x goes
out of scope, 'a2' will too, and will call A_delete).

Thanks


Interfacing with C libs: weeding through C/C++ macros and such in header files

2019-01-13 Thread Alec Stewart via Digitalmars-d-learn

Hello all!

So while I have a decent grasp on D, I've been having trouble 
figuring out specific projects that I could do in D, so I thought 
I'd maybe find a little C or C++ library I could transfer over to 
D. I decided to make my life easier and look for something that's 
just a single header file, and while that does make things easier 
there are a TON of macros and inline functions that it almost 
seems ridiculous and it's somewhat overwhelming.


Example without code; for some reason a macro is defined for the 
stdlib functions `malloc`, `realloc`, and `free`. Maybe it's just 
because I don't have any pro experience with C or C++, but that 
seems a bit excessive. Or I could just be dumb.


Example with code (because I need help figuring out how whether I 
even need this or not):


#ifndef RS_API
#ifdef RS_NOINLINE
/* GCC version 3.1 required for the no inline attribute. */
#if RS_GCC_VERSION > 30100
#define RS_API static __attribute__((noinline))
#elif defined(_MSC_VER)
#define RS_API static __declspec(noinline)
#else
#define RS_API static
#endif
#elif RS_C99
#define RS_API static inline
#elif defined(__GNUC__)
#define RS_API static __inline__
#elif defined(_MSC_VER)
#define RS_API static __forceinline
#else
#define RS_API static
#endif
#endif

I understand what it's doing, but do I really any of this with D? 
And then there's this inline function


#define RS_DATA_SIZE(f, s, input) 
  \
	do { 
   \

if (rs_is_heap(input))  \
f(s, input->heap.buffer, rs_heap_len(input));   \
else\
f(s, input->stack.buffer, rs_stack_len(input)); \
} while (0)

so yea. There's a little over 300 lines of preprocessor stuff. My 
question is how you all determine what to carry over from C libs 
in terms of preprocessor stuff. I imagine most useful values 
everyone just makes an enum for, and structs and unions are kept.


Thanks for any help you give!


Re: how to handle memory ownership when interfacing with C/C++ via internal pointers

2013-10-15 Thread timotheecour

On Thursday, 10 October 2013 at 23:02:29 UTC, Timothee Cour wrote:

Short version:
I have a struct A* aptr allocated in C/C++ with an internal
pointer aptr->ptr (say a double*)
I want to store a reference x (say double[]) in D to aptr only 
through
aptr->ptr, not through aptr directly as it's inconvenient in my 
use case.


How do I achieve that, so that when x goes out of scope, some 
deallocator

for aptr will be called ?

Long version:

suppose I have C++ code:
struct A{
  double*ptr;
  A(size_t n){ptr=(double*)malloc(n);}
  ~A(){free(ptr);}
};

and a D wrapper around it:
extern(C){struct A; A*A_new(size_t n); void A_delete(A*a);
double*A_ptr(A*a);}

I want to use it as follows:

double[] get_x(size_t n){
 return A_new(n).A_ptr[0..n];
}

void main(){
  double[]x=get_x(n);
// do something with x;
}


It's trivial to handle this via a class wrapper:
class A2{
A*a;
this(size_t n){a=A_new(n);}
~this(){A_delete(n);}
double*ptr(){return A_ptr(a);}
}
double[] get_x(size_t n){
 auto a2=new A2(n);
 return a2.ptr;
//this doesn't help much though, A2 will go out of scope when 
this function

exits.
}


but I don't want to maintain objects of class A2 around, just 
double[]

slices as above.

Is there some magic involving core.memory.addRoot,addRange 
(etc) I can use
so that a2 stays alive as long as x stays alive? (in which case 
when x goes

out of scope, 'a2' will too, and will call A_delete).

Thanks


Ping?
Is anything above unclear?

here are more details (in a simplified setting):

say, I have an image class D_image which has fields:
ubyte* ptr //pointer to memory
uint[2] size;

I'd like to interface with, say, a swig-wrapped opencv C++ image 
class Swig_image, so that when an object d_image:D_image goes out 
of scope (and its pointer ptr also goes out of scope), (with 
d_image constructed from an object swig_image of type 
Swig_image), then swig_image will also go out of scope.


again, this can be done by adding a field to D_image (say of type 
void* to make it work with any source), buy I'm wondering whether 
this can be achieved without adding this field, with some GC 
magic associating a pointer (ptr) to another pointer (cast(void*) 
swig_image).


This would make interfacing with C++ libs much easier as there 
would be no bookkeeping in user code.









Re: Interfacing with C libs: weeding through C/C++ macros and such in header files

2019-01-13 Thread Alex via Digitalmars-d-learn

On Sunday, 13 January 2019 at 22:40:57 UTC, Alec Stewart wrote:
Example without code; for some reason a macro is defined for 
the stdlib functions `malloc`, `realloc`, and `free`. Maybe 
it's just because I don't have any pro experience with C or 
C++, but that seems a bit excessive. Or I could just be dumb.




These three are members of the standard library in D.
https://dlang.org/phobos/core_memory.html

Example with code (because I need help figuring out how whether 
I even need this or not):


#ifndef RS_API
#ifdef RS_NOINLINE
/* GCC version 3.1 required for the no inline attribute. */
#if RS_GCC_VERSION > 30100
#define RS_API static __attribute__((noinline))
#elif defined(_MSC_VER)
#define RS_API static __declspec(noinline)
#else
#define RS_API static
#endif
#elif RS_C99
#define RS_API static inline
#elif defined(__GNUC__)
#define RS_API static __inline__
#elif defined(_MSC_VER)
#define RS_API static __forceinline
#else
#define RS_API static
#endif
#endif

I understand what it's doing, but do I really any of this with 
D? And then there's this inline function


#define RS_DATA_SIZE(f, s, input)
  \
do {
   \
if (rs_is_heap(input))  \
f(s, input->heap.buffer, rs_heap_len(input));   \
else\
f(s, input->stack.buffer, rs_stack_len(input)); \
} while (0)

so yea. There's a little over 300 lines of preprocessor stuff. 
My question is how you all determine what to carry over from C 
libs in terms of preprocessor stuff. I imagine most useful 
values everyone just makes an enum for, and structs and unions 
are kept.


Thanks for any help you give!


At first, I would suggest to try out some automatic converters, 
which are written by the community:

https://wiki.dlang.org/Bindings#Binding_generators
especially dstep and dpp

I had some ambivalent experience with the procedure of converting 
C --> D, but there is C code out there, which behaves very well 
in this respect... So, generally, I pursued the tactics of

automatic conversion
trying to compile
rewriting missing parts.

Also, if there is a possibility to compile the C/C++ library, you 
could provide the interface only to the functions you need. Then, 
you reuse the existent code directly and interface the library by 
declaring the interfaces as extern in your D sources.

https://dlang.org/spec/attribute.html#linkage


Re: Interfacing with C libs: weeding through C/C++ macros and such in header files

2019-01-13 Thread Alec Stewart via Digitalmars-d-learn

On Sunday, 13 January 2019 at 23:23:50 UTC, Alex wrote:

These three are members of the standard library in D.
https://dlang.org/phobos/core_memory.html




Ah, yea that's way easier.

At first, I would suggest to try out some automatic converters, 
which are written by the community:

https://wiki.dlang.org/Bindings#Binding_generators
especially dstep and dpp




That would make it easier because there's a lot of preprocessor 
stuff that ends up being circular references if I use `enum` or 
`const`.


Also, if there is a possibility to compile the C/C++ library, 
you could provide the interface only to the functions you need. 
Then, you reuse the existent code directly and interface the 
library by declaring the interfaces as extern in your D sources.

https://dlang.org/spec/attribute.html#linkage



That would also be easier. :P Thanks!


Re: Interfacing with C libs: weeding through C/C++ macros and such in header files

2019-01-13 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 13 January 2019 at 22:40:57 UTC, Alec Stewart wrote:



Example without code; for some reason a macro is defined for 
the stdlib functions `malloc`, `realloc`, and `free`. Maybe 
it's just because I don't have any pro experience with C or 
C++, but that seems a bit excessive. Or I could just be dumb.


Generally this is done to allow the compile-time configuration of 
memory allcoators. Back in my C days I had a little memory module 
that tracked total allocated and unallocated bytes and logged a 
few stats to a file at shutdown. I used macros to switch between 
it and the default stdlib calls.



I understand what it's doing, but do I really any of this with 
D?


No.


And then there's this inline function

#define RS_DATA_SIZE(f, s, input)
  \
do {
   \
if (rs_is_heap(input))  \
f(s, input->heap.buffer, rs_heap_len(input));   \
else\
f(s, input->stack.buffer, rs_stack_len(input)); \
} while (0)



Generally, this sort of thing can be moved into a D function or 
template if it's repeated in several places. Without the 
do...while, of course. And in case you're unfamiliar with its 
purpose here:


https://stackoverflow.com/questions/154136/why-use-apparently-meaningless-do-while-and-if-else-statements-in-macros