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.


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 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.


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?




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!!!


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 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-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.


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-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: 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 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.


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

2020-06-10 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 to C++: Cannot access value from namespace

2019-09-07 Thread Andrew Edwards via Digitalmars-d-learn

On Saturday, 7 September 2019 at 12:39:25 UTC, Ali Çehreli wrote:

On 09/07/2019 03:26 AM, Andrew Edwards wrote:

> [1] I did not declare any of the other member variables from
the struct,
> don't know if this is a source of the problem.

Yes, it definitely is a problem. The members are accessed as 
byte offsets into their objects. Without defining the other 
members, your D-side member is read from offset 0, which is not 
the case on the C++ side.


However, I'm still not sure whether that would solve the 
problem due to the following differences between C++ and D:


That was it, and yes it solves the problem. There are far too 
many variables to define at the moment so I found the offsetof() 
and defined a "void[offset] pad" to take care of the issue for 
right now.


Thanks,
Andrew



Re: Interfacing to C++: Cannot access value from namespace

2019-09-07 Thread Ali Çehreli via Digitalmars-d-learn

On 09/07/2019 03:26 AM, Andrew Edwards wrote:

> [1] I did not declare any of the other member variables from the struct,
> don't know if this is a source of the problem.

Yes, it definitely is a problem. The members are accessed as byte 
offsets into their objects. Without defining the other members, your 
D-side member is read from offset 0, which is not the case on the C++ side.


However, I'm still not sure whether that would solve the problem due to 
the following differences between C++ and D:


- No 'volatile' keyword in D (not in your example code anyway)

- Variables are thread-local by default in D

But I guess extern(C++) takes care of those differences. (?) So, it 
should work after defining all the members. :)


Ali



Re: Interfacing to C++: Cannot access value from namespace

2019-09-07 Thread Andrew Edwards via Digitalmars-d-learn
On Saturday, 7 September 2019 at 12:30:53 UTC, Andrew Edwards 
wrote:
On Saturday, 7 September 2019 at 12:24:49 UTC, Ali Çehreli 
wrote:

On 09/07/2019 03:26 AM, Andrew Edwards wrote:

>  float continuallyUpdatedValue;
>  float continuallyChangingValue; // [1]

They mean the same thing for an English speaker but compilers 
don't know that (yet?). :)


Ali


LOL. Sorry about that, I decided to change the variable name in 
the middle of writing the post and missed one.


Andrew


The problem existed prior to this naming mishap and remains after 
correcting it.


Re: Interfacing to C++: Cannot access value from namespace

2019-09-07 Thread Andrew Edwards via Digitalmars-d-learn

On Saturday, 7 September 2019 at 12:24:49 UTC, Ali Çehreli wrote:

On 09/07/2019 03:26 AM, Andrew Edwards wrote:

>  float continuallyUpdatedValue;
>  float continuallyChangingValue; // [1]

They mean the same thing for an English speaker but compilers 
don't know that (yet?). :)


Ali


LOL. Sorry about that, I decided to change the variable name in 
the middle of writing the post and missed one.


Andrew


Re: Interfacing to C++: Cannot access value from namespace

2019-09-07 Thread Ali Çehreli via Digitalmars-d-learn

On 09/07/2019 03:26 AM, Andrew Edwards wrote:

>  float continuallyUpdatedValue;
>  float continuallyChangingValue; // [1]

They mean the same thing for an English speaker but compilers don't know 
that (yet?). :)


Ali



Interfacing to C++: Cannot access value from namespace

2019-09-07 Thread Andrew Edwards via Digitalmars-d-learn
I'm running into the following issue when attempting to interface 
with C++:


// C++

namespace MySpace
{
MyType& GetData();
}

struct MyType
{
// ...
float continuallyUpdatedValue;
// ...
};

// call site
MySpace::GetData().continuallyUpdatedValue;

// D

extern (C++, MySpace) MyType* GetData();

struct MyType
{
float continuallyChangingValue; // [1]
}

// call site
MySpace.GetData().continuallyUpdatedValue; // <--- This is not 
being updated by C++


[1] I did not declare any of the other member variables from the 
struct, don't know if this is a source of the problem.


Re: Memory management by interfacing C/C++

2019-04-29 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Monday, 29 April 2019 at 14:38:54 UTC, 9il wrote:
On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş 
wrote:

[...]


Hello Ferhat,

You can use RCArray!T or Slice!(RCI!T) [1, 2] as common thread 
safe @nogc types for D and C++ code.

See also integration C++ example [3] and C++ headers [4].


RCArray (fixed length)
[1] http://mir-algorithm.libmir.org/mir_rc_array.html
RCSlice (allows to get subslices)
[2] 
http://mir-algorithm.libmir.org/mir_ndslice_allocation.html#rcslice

C++ integration example
[3] 
https://github.com/libmir/mir-algorithm/tree/master/cpp_example

C++ headers
[4] 
https://github.com/libmir/mir-algorithm/tree/master/include/mir
An opencv d binding using ndslice substituting cv::Mat would be 
useful like opencv-python using numpy. However, I started opencvd 
about a month ago, and I am very new to d. For now, I am the only 
contributor with zero mir.ndslice experience. When I gain more 
experience with ndslice, I would try it as substitution for 
cv::Mat. Thank you for links 9il. I will take a look at them.


Re: Memory management by interfacing C/C++

2019-04-29 Thread 9il via Digitalmars-d-learn
On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş 
wrote:

Hi,

I am wrapping some C++ code for my personal project (opencvd), 
and I am creating so many array pointers at cpp side and 
containing them in structs. I want to learn if I am leaking 
memory like crazy, although I am not facing crashes so far. Is 
GC of D handling things for me? Here is an example:


```
//declaration in d
struct IntVector {
int* val;
int length;
}

// in cpp
typedef struct IntVector {
int* val;
int length;
} IntVector;

// cpp function returning a struct containing an array pointer 
allocated with "new" op.

IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){
std::vector iv;
sd->getLeadingEdgeList(iv);

int *cintv = new int[iv.size()]; // I don't call delete 
anywhere?


for(size_t i=0; i < iv.size(); i++){
cintv[i] = iv[i];
}
IntVector ret = {cintv, (int)iv.size()};
return ret;
};

// call extern c function in d:
extern (C) IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2d sd);

int[] getLeadingEdgeList(){
IntVector intv = Subdiv2D_GetLeadingEdgeList(this);
int[] ret = intv.val[0..intv.length]; // just D magic. 
Still no delete anywhere!

return ret;
}
```

The question is now: what will happen to "int *cintv" which is 
allocated with new operator in cpp code? I have many code 
similar in the project, but I have not encounter any problem so 
far even in looped video processings. Is GC of D doing 
deallocation automagically?

https://github.com/aferust/opencvd


Hello Ferhat,

You can use RCArray!T or Slice!(RCI!T) [1, 2] as common thread 
safe @nogc types for D and C++ code.

See also integration C++ example [3] and C++ headers [4].


RCArray (fixed length)
[1] http://mir-algorithm.libmir.org/mir_rc_array.html
RCSlice (allows to get subslices)
[2] 
http://mir-algorithm.libmir.org/mir_ndslice_allocation.html#rcslice

C++ integration example
[3] 
https://github.com/libmir/mir-algorithm/tree/master/cpp_example

C++ headers
[4] 
https://github.com/libmir/mir-algorithm/tree/master/include/mir




Re: Memory management by interfacing C/C++

2019-04-29 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Monday, 29 April 2019 at 00:53:34 UTC, Paul Backus wrote:
On Sunday, 28 April 2019 at 23:10:24 UTC, Ferhat Kurtulmuş 
wrote:
You are right. I am rewriting the things using mallocs, and 
will use core.stdc.stdlib.free on d side. I am not sure if I 
can use core.stdc.stdlib.free to destroy arrays allocated with 
new op.


core.stdc.stdlib.free is (as the name suggests) the standard C 
`free` function. As such, it can only be used to free memory 
allocated by the standard C functions `malloc`, `calloc`, and 
`realloc`. This is the same in D as it is in C and C++.


Thank you. It is now like:

/* c/cpp side */
extern (C) void deleteArr(void* arr);

void deleteArr(void* arr){
delete[] arr;
}

struct IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){
std::vector iv;
sd->getLeadingEdgeList(iv);
int *cintv = new int[iv.size()];
for(size_t i=0; i < iv.size(); i++){
cintv[i] = iv[i];
}
IntVector ret = {cintv, (int)iv.size()};
return ret;
};

/* c/cpp side */

...
int[] getLeadingEdgeList(){ // d function
IntVector intv = Subdiv2D_GetLeadingEdgeList(this);
int[] ret = intv.val[0..intv.length].dup;
deleteArr(intv.val);
return ret;
}
...



Re: Memory management by interfacing C/C++

2019-04-28 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 28 April 2019 at 23:10:24 UTC, Ferhat Kurtulmuş wrote:
You are right. I am rewriting the things using mallocs, and 
will use core.stdc.stdlib.free on d side. I am not sure if I 
can use core.stdc.stdlib.free to destroy arrays allocated with 
new op.


core.stdc.stdlib.free is (as the name suggests) the standard C 
`free` function. As such, it can only be used to free memory 
allocated by the standard C functions `malloc`, `calloc`, and 
`realloc`. This is the same in D as it is in C and C++.


Re: Memory management by interfacing C/C++

2019-04-28 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Sunday, 28 April 2019 at 03:54:17 UTC, Paul Backus wrote:
On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş 
wrote:

Hi,

I am wrapping some C++ code for my personal project (opencvd), 
and I am creating so many array pointers at cpp side and 
containing them in structs. I want to learn if I am leaking 
memory like crazy, although I am not facing crashes so far. Is 
GC of D handling things for me? Here is an example:


[...]

The question is now: what will happen to "int *cintv" which is 
allocated with new operator in cpp code? I have many code 
similar in the project, but I have not encounter any problem 
so far even in looped video processings. Is GC of D doing 
deallocation automagically?

https://github.com/aferust/opencvd


D's GC only collects memory allocated with D's `new` operator. 
Memory allocated by C++'s `new` operator must be freed by C++'s 
`delete` operator.


You are right. I am rewriting the things using mallocs, and will 
use core.stdc.stdlib.free on d side. I am not sure if I can use 
core.stdc.stdlib.free to destroy arrays allocated with new op.


Re: Memory management by interfacing C/C++

2019-04-27 Thread Paul Backus via Digitalmars-d-learn
On Saturday, 27 April 2019 at 22:25:58 UTC, Ferhat Kurtulmuş 
wrote:

Hi,

I am wrapping some C++ code for my personal project (opencvd), 
and I am creating so many array pointers at cpp side and 
containing them in structs. I want to learn if I am leaking 
memory like crazy, although I am not facing crashes so far. Is 
GC of D handling things for me? Here is an example:


[...]

The question is now: what will happen to "int *cintv" which is 
allocated with new operator in cpp code? I have many code 
similar in the project, but I have not encounter any problem so 
far even in looped video processings. Is GC of D doing 
deallocation automagically?

https://github.com/aferust/opencvd


D's GC only collects memory allocated with D's `new` operator. 
Memory allocated by C++'s `new` operator must be freed by C++'s 
`delete` operator.


Memory management by interfacing C/C++

2019-04-27 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

Hi,

I am wrapping some C++ code for my personal project (opencvd), 
and I am creating so many array pointers at cpp side and 
containing them in structs. I want to learn if I am leaking 
memory like crazy, although I am not facing crashes so far. Is GC 
of D handling things for me? Here is an example:


```
//declaration in d
struct IntVector {
int* val;
int length;
}

// in cpp
typedef struct IntVector {
int* val;
int length;
} IntVector;

// cpp function returning a struct containing an array pointer 
allocated with "new" op.

IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2D sd){
std::vector iv;
sd->getLeadingEdgeList(iv);

int *cintv = new int[iv.size()]; // I don't call delete 
anywhere?


for(size_t i=0; i < iv.size(); i++){
cintv[i] = iv[i];
}
IntVector ret = {cintv, (int)iv.size()};
return ret;
};

// call extern c function in d:
extern (C) IntVector Subdiv2D_GetLeadingEdgeList(Subdiv2d sd);

int[] getLeadingEdgeList(){
IntVector intv = Subdiv2D_GetLeadingEdgeList(this);
int[] ret = intv.val[0..intv.length]; // just D magic. Still 
no delete anywhere!

return ret;
}
```

The question is now: what will happen to "int *cintv" which is 
allocated with new operator in cpp code? I have many code similar 
in the project, but I have not encounter any problem so far even 
in looped video processings. Is GC of D doing deallocation 
automagically?

https://github.com/aferust/opencvd


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




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 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


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: 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



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 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


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: 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++

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-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-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 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 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 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 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 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);


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


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 :)


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.


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: 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: 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 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.




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?!


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.


Re: D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-02 Thread via Digitalmars-d-learn

On Saturday, 1 November 2014 at 21:00:54 UTC, Kagamin wrote:
D claims compatibility with system C compiler, which usually 
have 32-bit int.


... and for C/C++ long which can be 32 or 64 bit, DMD recently 
introduced the types c_long and c_ulong. (Not released yet.)


Re: D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-02 Thread John Colvin via Digitalmars-d-learn
On Saturday, 1 November 2014 at 15:00:57 UTC, Shriramana Sharma 
via Digitalmars-d-learn wrote:

In the following pages:

http://dlang.org/interfaceToC.html
http://dlang.org/cpp_interface

the Data Type Compatibility section says D int is compatible 
with
C/C++ int. Isn't this actually false because D's integer types 
are
fixed-size whereas C/C++'s are variable? So D int is only 
compatible
with C++ int32_t, and who knows what that is typedef-ed to? 
Likewise

for uint, long, short etc.

So how to ensure, when calling C/C++, that the D int etc are 
being
mapped to the correctly-sized C/C++ type? Does the compiler 
ensure

that since the compatibility is being advertised as built-in?


Note this at the end of the Data Type Compatiblity section:

These equivalents hold for most C compilers. The C standard does 
not pin down the sizes of the types, so some care is needed.


D's built-in types do not change based on the companion C 
compiler. When linking to C, it is the programmers responsibility 
to ensure they are using the right types.


core.stdc.config can help deal with the most common 
inconsistencies.


Re: D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-02 Thread Mike Parker via Digitalmars-d-learn

On 11/2/2014 8:59 PM, Marc Schütz schue...@gmx.net wrote:

On Saturday, 1 November 2014 at 21:00:54 UTC, Kagamin wrote:

D claims compatibility with system C compiler, which usually have
32-bit int.


... and for C/C++ long which can be 32 or 64 bit, DMD recently
introduced the types c_long and c_ulong. (Not released yet.)


Those aren't new. They have been in core.stdc.config for quite some time.


Re: D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-02 Thread via Digitalmars-d-learn

On Sunday, 2 November 2014 at 12:37:13 UTC, Mike Parker wrote:

On 11/2/2014 8:59 PM, Marc Schütz schue...@gmx.net wrote:

On Saturday, 1 November 2014 at 21:00:54 UTC, Kagamin wrote:
D claims compatibility with system C compiler, which usually 
have

32-bit int.


... and for C/C++ long which can be 32 or 64 bit, DMD recently
introduced the types c_long and c_ulong. (Not released yet.)


Those aren't new. They have been in core.stdc.config for quite 
some time.


Ah, I see. But DMD now has support for mangling these types 
correctly, in commit c4e0de64.


Re: D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-02 Thread Sean Kelly via Digitalmars-d-learn

On Sunday, 2 November 2014 at 11:59:27 UTC, Marc Schütz wrote:

On Saturday, 1 November 2014 at 21:00:54 UTC, Kagamin wrote:
D claims compatibility with system C compiler, which usually 
have 32-bit int.


... and for C/C++ long which can be 32 or 64 bit, DMD recently 
introduced the types c_long and c_ulong. (Not released yet.)


c_long and c_ulong have existed as aliases in core.stdc since the 
beginning.  The change was to make them an explicit type so name 
mangling could be different.


Re: D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-02 Thread ponce via Digitalmars-d-learn

On Sunday, 2 November 2014 at 12:37:13 UTC, Mike Parker wrote:

On 11/2/2014 8:59 PM, Marc Schütz schue...@gmx.net wrote:

On Saturday, 1 November 2014 at 21:00:54 UTC, Kagamin wrote:
D claims compatibility with system C compiler, which usually 
have

32-bit int.


... and for C/C++ long which can be 32 or 64 bit, DMD recently
introduced the types c_long and c_ulong. (Not released yet.)


Those aren't new. They have been in core.stdc.config for quite 
some time.


c_long and c_ulong get used, should c_int and c_uint too in 
bindings?

Looks like fringe use case.


Re: D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-02 Thread Sean Kelly via Digitalmars-d-learn

On Sunday, 2 November 2014 at 16:53:06 UTC, ponce wrote:


c_long and c_ulong get used, should c_int and c_uint too in 
bindings?

Looks like fringe use case.


On common 32 and 64-bit platforms, the only type whose size 
changed between 32 and 64 bits is long, so the other aliases were 
deemed unnecessary.  It's possible that as D is ported to more 
platforms this will have to change, but I seriously hope not.


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 ஶ்ரீரமணஶர்மா श्रीरमणशर्मा



D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-01 Thread Shriramana Sharma via Digitalmars-d-learn
In the following pages:

http://dlang.org/interfaceToC.html
http://dlang.org/cpp_interface

the Data Type Compatibility section says D int is compatible with
C/C++ int. Isn't this actually false because D's integer types are
fixed-size whereas C/C++'s are variable? So D int is only compatible
with C++ int32_t, and who knows what that is typedef-ed to? Likewise
for uint, long, short etc.

So how to ensure, when calling C/C++, that the D int etc are being
mapped to the correctly-sized C/C++ type? Does the compiler ensure
that since the compatibility is being advertised as built-in?

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



Re: D int and C/C++ int etc not really compatible when interfacing to C/C++

2014-11-01 Thread Kagamin via Digitalmars-d-learn
D claims compatibility with system C compiler, which usually have 
32-bit int.


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: 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: 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.









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


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?



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 a...@lycus.org 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 seewebsitetocontac...@semitwist.com 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


Interfacing to C

2011-06-28 Thread Joshua Niehus
Hello,

I was trying to run the example on the Interfacing to C page (
http://www.d-programming-language.org/interfaceToC.html) and ran into few
issues. To get it to work as is i was .dup(ing) strings into new chars
with defined size and passing those with .ptr. Anyway it seemed like quite a
bit of work for something simple so I added const in the signatures and
things worked much more smoothly:

import std.stdio, std.string;

extern (C) int strcmp(const char* string1, const char* string2);

void main()
{
writeln(myDfunction(foo));
}

int myDfunction(const char[] s) {
return strcmp(std.string.toStringz(s), foo);
}

Was there a reason why the consts were left out?
if this is a typo I'd be happy to update the web page, would be good
experience for a noob like me. (never used GIT before and first time
participating in a community)

Thanks,
Josh


Re: Interfacing to C

2011-06-28 Thread Jimmy Cao
On Tue, Jun 28, 2011 at 11:15 PM, Joshua Niehus jm.nie...@gmail.com wrote:

 Hello,

 I was trying to run the example on the Interfacing to C page (
 http://www.d-programming-language.org/interfaceToC.html) and ran into few
 issues. To get it to work as is i was .dup(ing) strings into new chars
 with defined size and passing those with .ptr. Anyway it seemed like quite a
 bit of work for something simple so I added const in the signatures and
 things worked much more smoothly:

 import std.stdio, std.string;

 extern (C) int strcmp(const char* string1, const char* string2);

 void main()
 {
 writeln(myDfunction(foo));
 }

 int myDfunction(const char[] s) {
 return strcmp(std.string.toStringz(s), foo);
 }

 Was there a reason why the consts were left out?
 if this is a typo I'd be happy to update the web page, would be good
 experience for a noob like me. (never used GIT before and first time
 participating in a community)

 Thanks,
 Josh



I think it was written for D1, where strings are char[].
The code can be written like this:

import std.string;

extern (C) int strcmp(const char* string1, const char* string2);

int myDfunction(string s) {
return strcmp(toStringz(s), foo);
}


Re: Interfacing to C. extern (C) variables

2011-06-26 Thread Robert Clipsham

On 26/06/2011 20:54, Alex_Dovhal wrote:

I'd like to call C functions and use C variables in D module.
D calls C functions just fine, but how can I use C variables?


extern(C) extern int myCVar;

--
Robert
http://octarineparrot.com/


Re: Interfacing to C. extern (C) variables

2011-06-26 Thread Jimmy Cao
On Sun, Jun 26, 2011 at 5:00 PM, Alex_Dovhal alex_dov...@yahoo.com wrote:

 Robert Clipsham rob...@octarineparrot.com wrote:
  On 26/06/2011 20:54, Alex_Dovhal wrote:
  I'd like to call C functions and use C variables in D module.
  D calls C functions just fine, but how can I use C variables?
 
  extern(C) extern int myCVar;

 Thanks for answer. I've already tried that, it doesn't work for some
 reason:

 * file unit2.d:
 module unit;
 import std.stdio;
 extern(C) int func();
 extern(C) extern int c_var;

 void main()
 {
func();
writeln(In D);
writefln(c_var = %d, c_var);
writefln(c_var = %x, c_var);
 }

 Result:
 In C
 c_var = 1234
 c_var = 470200
 In D
 object.Error: Access Violation
 
 426DA4
 426C1B
 405BEB
 4057E7
 451099
 


 Found workaround, but it's extreme hack:

 *file test.c
 #include stdio.h
 int c_var;
 //int* ref_c_var()
 //{
 //return c_var;
 //}

 #define REF_DECL(type, name) type* ref_ ## name () {return name;}

 REF_DECL(int, c_var)

 int func()
 {
c_var = 1234;
printf(In C\n);
printf(c_var = %d\n, c_var);
printf(c_var = %x\n, c_var);
return 0;
 }

 *file: unit1.d:
 module unit;
 import std.stdio;

 extern(C) int func();

 string C_VAR(string type, string name)
 {
return
extern (C) ~ type ~ * ref_ ~ name ~ ();~
  ~ ref  ~ type ~   ~ name ~(){return *ref_~name~();};
 }

 mixin(C_VAR(int, c_var));

 void main()
 {
func();
writeln(In D);
writefln(c_var = %d, c_var);
writefln(c_var = %x, c_var);
 }




It works for me like this:

extern(C){
   __gshared int c_var;
   int func();
}


Re: Interfacing to C. extern (C) variables

2011-06-26 Thread Alex_Dovhal
Jimmy Cao jcao...@gmail.com wrote:
It works for me like this:

extern(C){
   __gshared int c_var;
   int func();
}

Thanks. 




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 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 leav...@alone.com 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 leav...@alone.com 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: 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 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.


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?


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 Steven Schveighoffer
On Fri, 25 Feb 2011 20:06:04 -0500, bearophile bearophileh...@lycos.com  
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