March 24, 2011
Hmm... Spent a few hours trying to figure out how to update GCC and
all to conform to the requirements for 2.0.52, and at seems that it
compiles my small test program just fine, but it fails on compiling
the main project for some reason. And the linker outputs
half-scrambled things. Anyway, here's all the output that shows how
I'm trying to build the thing:
http://pastebin.com/j7bE76bn
It seems that it for some odd reason doesn't want to link the imports,
and I don't see why is that, since my small test program works, and it
uses basically the same thing...
March 25, 2011
Oh, I found the problem... It's just me forgetting that my library has to go before phobos to compile it. So right now it works perfectly! Thanks!
March 27, 2011
OK, now I have a question about passing variables. In D, I have a dynamic array of strings and I want C to get that array. Yet C supports neither dynamic arrays nor strings. So is there a way to accomplish this?
March 27, 2011
Dainius (GreatEmerald):

> OK, now I have a question about passing variables. In D, I have a dynamic array of strings and I want C to get that array. Yet C supports neither dynamic arrays nor strings. So is there a way to accomplish this?

To use a D data structure from C you need first of all to know what exactly those data structures are.

In this case one solution is to create (from D) a dynamic array of char*, then perform a map!toStringz to convert the strings to C strings, and then call the C code with the ptr and length of this dynamic array of pointers.

There are other solutions, according to the amount of data you want to copy or according to the amount of C code you want to write to access the D data structures.

Bye,
bearophile
March 27, 2011
Well, the situation is like this: D creates a list of names of files
that should be loaded by C. C then takes the list, uses it to load the
files, then stores both the pointers to the loaded files and the names
of the files in an array of structs. Then when C wants to access the
files, it asks D about which file to access, which then sends the file
name, and C compares the known file names and on finding a match,
accesses the file.
So that means that the array should be pretty much read-only there,
but C needs to know how big the newly created array of structs has to
be. As for how long the list of file names will be - it's determined
by the configuration, so it will be anywhere from 1 to around 300 or
even more.
March 27, 2011
Dainius (GreatEmerald):

> Well, the situation is like this: D creates a list of names of files
> that should be loaded by C. C then takes the list, uses it to load the
> files, then stores both the pointers to the loaded files and the names
> of the files in an array of structs. Then when C wants to access the
> files, it asks D about which file to access, which then sends the file
> name, and C compares the known file names and on finding a match,
> accesses the file.
> So that means that the array should be pretty much read-only there,
> but C needs to know how big the newly created array of structs has to
> be. As for how long the list of file names will be - it's determined
> by the configuration, so it will be anywhere from 1 to around 300 or
> even more.

So?

Bye,
bearophile
March 27, 2011
Dainius (GreatEmerald) Wrote:

> Well, the situation is like this: D creates a list of names of files
> that should be loaded by C. C then takes the list, uses it to load the
> files, then stores both the pointers to the loaded files and the names
> of the files in an array of structs. Then when C wants to access the
> files, it asks D about which file to access, which then sends the file
> name, and C compares the known file names and on finding a match,
> accesses the file.
> So that means that the array should be pretty much read-only there,
> but C needs to know how big the newly created array of structs has to
> be. As for how long the list of file names will be - it's determined
> by the configuration, so it will be anywhere from 1 to around 300 or
> even more.

If you want to pass an array of file names to C, you must pass it as a char**, accomplished as bearophile has stated.

Since your C program is asking D which files to work with next why doesn't it load the file at that time? If the file is processed multiple times, you can still cache the data and just check if it is already cached.
March 27, 2011
Hmm, if I was to do it from C, I would have to deal with all the allocation, since I don't know how large the array is going to be when it's complete, while D doesn't need to know since it uses dynamic arrays.
March 29, 2011
All right, I solved that part of the problem by creating a linked
list. However, getting the string out of D is still problematic,
namely because toStringz() gives me an immutable char*, and I don't
seem to be able to pass those, since I can't assign those to immutable
variables outside their constructors. Also, if I use this:
//D:
void GetString()
{
    ReceiveString(toStringz(StringD));
}

//C:
extern(C) void ReceiveString(char* String)
{
    StringC = String;
}

DMD gives me "Error: undefined identifier ReceiveString" for some reason.
March 29, 2011
Oh, never mind. About sending strings, I got it working, I just had to create a function like this in D:

immutable(char)* GetString()
{
    return StringD.toStringz();
}

As for D not compiling, I had to declare it in D, d'oh :D And that extern is in the wrong place there.