Re: Linking a C program with D library

2018-08-15 Thread Joe via Digitalmars-d-learn

On Wednesday, 15 August 2018 at 06:39:50 UTC, Mike Parker wrote:
String literals are implicitly convertible to const(char)* and 
are guaranteed to be nul-terminated like a C string, so this 
works:


[...]

Does that help?


Yes, indeed. I think I possibly read about literal strings being 
nul-terminated somewhere but it must've slipped my mind.


Re: Linking a C program with D library

2018-08-15 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 15 August 2018 at 02:40:22 UTC, Joe wrote:



I understand that, Mike. However if I'm not mistaken given 
something in C like


char* strs[] = { "This", "is a", "test"};

AFAIK, even with -betterC and an extern (C), the literals will 
still be understood by D as type "string", and there is no 
other way around it, right?


I could put the array and the function in its own C file for 
the time being, but instead chose to replace the toStringz by a 
small hack: use memcpy to copy the string to a stack fixed, big 
enough array and a NUL terminator.


String literals are implicitly convertible to const(char)* and 
are guaranteed to be nul-terminated like a C string, so this 
works:


import core.stdc.stdio;
extern(C) void main()
{
const(char)* foo = "foo";
puts(foo);
}
https://run.dlang.io/is/FZSXc3

For plain char*, a simple cast works:

char* foo = cast(char*)"foo";

The problem is with the array initializer, as the C-style {x, y, 
z} only works on structs in D, and D's [x, y, z] requires 
TypeInfo, which isn't available in -betterC, a problem you run 
into even when your array is string[].


However, the initializer works fine with static arrays in 
-betterC, so this works:


import core.stdc.stdio;
extern(C):

void some_c_func(const char** strs, size_t numStrs) {
for(size_t i=0; ihttps://run.dlang.io/is/pxmGyh

Does that help?



Re: Linking a C program with D library

2018-08-14 Thread Joe via Digitalmars-d-learn

On Wednesday, 15 August 2018 at 01:56:34 UTC, Mike Parker wrote:
The correct thing to do is to keep the original C function 
signatures in the converted code, i.e. don't change char* to 
string[]. And don't use anything from Phobos internally that 
requires linking. In other words, treat your converted code as 
C code in a D module as much as possible. Only when the 
conversion is complete and everything is in D do you start 
pulling in the D features.


I understand that, Mike. However if I'm not mistaken given 
something in C like


char* strs[] = { "This", "is a", "test"};

AFAIK, even with -betterC and an extern (C), the literals will 
still be understood by D as type "string", and there is no other 
way around it, right?


I could put the array and the function in its own C file for the 
time being, but instead chose to replace the toStringz by a small 
hack: use memcpy to copy the string to a stack fixed, big enough 
array and a NUL terminator.


Re: Linking a C program with D library

2018-08-14 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 14 August 2018 at 23:05:26 UTC, Joe wrote:
I'm attempting a piecemeal conversion of some C programs. I've 
converted a few that depend on C modules that are in a library 
and now I'm sort of in the middle of converting those C 
modules. One of them has an array of strings, i.e., array of 
char*, which most easily translated to D's string[]. However, 
the array is used by a function that expects a const char*, so 
I had to use toStringz to pass those values.


Now there are some C programs that haven't been converted yet, 
but they depend on the function above. When linking those 
programs, the linker complains about an undefined reference to 
the mangled name of std.string.toStringz.


What is the most appropriate way around this? Is there a way to 
declare an array of const char* and initialize it to literal 
strings? Or can the mangled name (and Phobos library) somehow 
be made visible to the linker?


The correct thing to do is to keep the original C function 
signatures in the converted code, i.e. don't change char* to 
string[]. And don't use anything from Phobos internally that 
requires linking. In other words, treat your converted code as C 
code in a D module as much as possible. Only when the conversion 
is complete and everything is in D do you start pulling in the D 
features.


Linking a C program with D library

2018-08-14 Thread Joe via Digitalmars-d-learn
I'm attempting a piecemeal conversion of some C programs. I've 
converted a few that depend on C modules that are in a library 
and now I'm sort of in the middle of converting those C modules. 
One of them has an array of strings, i.e., array of char*, which 
most easily translated to D's string[]. However, the array is 
used by a function that expects a const char*, so I had to use 
toStringz to pass those values.


Now there are some C programs that haven't been converted yet, 
but they depend on the function above. When linking those 
programs, the linker complains about an undefined reference to 
the mangled name of std.string.toStringz.


What is the most appropriate way around this? Is there a way to 
declare an array of const char* and initialize it to literal 
strings? Or can the mangled name (and Phobos library) somehow be 
made visible to the linker?