www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - SImple C++ code to D

reply "Alexandre" <alebencz gmail.com> writes:
I have this code in C++

//...
     char image[0x800];
//...
     auto dosh = reinterpret_cast<IMAGE_DOS_HEADER*>(&image[0]);
     dosh->e_magic = *(WORD*)"MZ";
     dosh->e_cblp = 0x90;
     dosh->e_cp = 3;
     dosh->e_cparhdr = 4;
     dosh->e_maxalloc = 0xffff;
     dosh->e_sp = 0xb8;
     dosh->e_lfarlc = 0x40;
     dosh->e_lfanew = 0x80;
     BYTE stub[] = { 0xb8, 0x01, 0x4c, 0xcd, 0x21 };
     memcpy(&image[0x40], stub, sizeof(stub));


I maded this in D:

module main;

import std.stdio;
import std.c.windows.windows;

struct _IMAGE_DOS_HEADER
{
	WORD e_magic;
	WORD e_cblp;
	WORD e_cp;
	WORD e_crlc;
	WORD e_cparhdr;
	WORD e_minalloc;
	WORD e_maxalloc;
	WORD e_ss;
	WORD e_sp;
	WORD e_csum;
	WORD e_ip;
	WORD e_cs;
	WORD e_lfarlc;
	WORD e_ovno;
	WORD e_res[4];
	WORD e_oemid;
	WORD e_oeminfo;
	WORD e_res2[10];
	LONG e_lfanew;
}
alias IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
alias PIMAGE_DOS_HEADER = _IMAGE_DOS_HEADER*;

char image[0x800];

void main(string[] args)
{
	auto dosh = cast(IMAGE_DOS_HEADER*)&image[0];
	//dosh.e_magic = 0x5A4D;
	dosh.e_magic = cast(WORD*)("MZ");

	auto stub = [0xb8, 0x01, 0x4c, 0xcd, 0x21];
	dmemcpy(&image[0x40], stub, stub.sizeof);
}

void * dmemcpy ( void * destination, const void * source, size_t 
num ) pure nothrow
{
	(cast(ubyte*)destination)[0 ..
		num][]=(cast(const(ubyte)*)source)[0 .. num];
	return destination;
}

But I got errors in this:
dmemcpy(&image[0x40], stub, stub.sizeof);

and in the cast of "MZ" to Word*
How is the best way to solve this ?
Jul 13 2014
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 13 July 2014 at 18:48:01 UTC, Alexandre wrote:
 	dosh.e_magic = cast(WORD*)("MZ");
should be: dosh.e_magic = cast(WORD*)("MZ".ptr);
Jul 13 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 	WORD e_res[4];
In D it's better to write: WORD[4] e_res;
 char image[0x800];
Note this is a thread-local variable. If you need a module-local variable you have to write: __gshared char[0x800] image;
 void main(string[] args)
If you don't need the args, then write: void main() In D we usually indent using 4 spaces.
 	auto dosh = cast(IMAGE_DOS_HEADER*)&image[0];
Perhaps better (untested): auto dosh = cast(IMAGE_DOS_HEADER*)image.ptr;
 	dosh.e_magic = cast(WORD*)("MZ");
Try (assuming word is 2 bytes long): dosh.e_magic = cast(WORD*)"MZ".ptr;
 	auto stub = [0xb8, 0x01, 0x4c, 0xcd, 0x21];
Try to use: immutable ubyte[5] stub = [0xb8, 0x01, 0x4c, 0xcd, 0x21];
 	dmemcpy(&image[0x40], stub, stub.sizeof);
 }

 void * dmemcpy ( void * destination, const void * source, 
 size_t num ) pure nothrow
 {
 	(cast(ubyte*)destination)[0 ..
 		num][]=(cast(const(ubyte)*)source)[0 .. num];
 	return destination;
 }
In D most cases you can avoid to use "void" as argument type. Also try to minimize the use of casts. And in D the "*" of pointers is written on the left, so you write "int* p" and not "int *p". Also in that function you don't mutate "num", so put a "in" before "size_t".
 But I got errors in this:
 dmemcpy(&image[0x40], stub, stub.sizeof);
What errors? Your code with some changes, but more improvements are possible (untested): import std.stdio; import core.stdc.string; import std.c.windows.windows; struct IMAGE_DOS_HEADER { WORD e_magic, e_cblp, e_cp, e_crlc, e_cparhdr, e_minalloc, e_maxalloc, e_ss, e_sp, e_csum, e_ip, e_cs, e_lfarlc, e_ovno; WORD[4] e_res; WORD e_oemid; WORD e_oeminfo; WORD[10] e_res2; LONG e_lfanew; } alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*; __gshared char[0x800] image; void main() { auto dosh = cast(IMAGE_DOS_HEADER*)image.ptr; dosh.e_magic = cast(WORD)*"MZ".ptr; immutable stub = x"b8 01 4c cd 21"; memcpy(&image[IMAGE_DOS_HEADER.sizeof], stub.ptr, stub.length); } Bye, bearophile
Jul 13 2014
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Sunday, 13 July 2014 at 18:48:01 UTC, Alexandre wrote:
 char image[0x800];
Better use `ubyte[0x800] image` here. `char[]` is only for UTF-8 strings.
Jul 13 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Marc Schütz:

 Better use `ubyte[0x800] image` here. `char[]` is only for 
 UTF-8 strings.
Right, sorry. Bye, bearophile
Jul 13 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
Ok, thanks thanks!!!
Have a lot of thinks I need to learn....

When I generate the exe file, something is wrong with this:
dosh.e_magic = cast(WORD)*"MZ".ptr;

When the PE file is generate in EXE have just the "M" of "MZ"...
Jul 13 2014
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/13/2014 05:21 PM, Alexandre wrote:
 Ok, thanks thanks!!!
 Have a lot of thinks I need to learn....

 When I generate the exe file, something is wrong with this:
 dosh.e_magic = cast(WORD)*"MZ".ptr;

 When the PE file is generate in EXE have just the "M" of "MZ"...
You put the * outside the cast. bearophile had dosh.e_magic = cast(WORD*)"MZ".ptr; However, one needs to copy the content to e_magic, which happens to be a WORD. The endianness may be off but it should be something like this: import std.stdio; void main() { alias WORD = ushort; WORD w = *cast(WORD*)"MZ".ptr; writefln("%02x", w); } Ali
Jul 13 2014
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 When the PE file is generate in EXE have just the "M" of "MZ"...
Let's try again, is this better? import std.c.windows.windows: WORD, LONG; struct IMAGE_DOS_HEADER { WORD e_magic = ('M' << 8) + 'Z', e_cblp, e_cp, e_crlc, e_cparhdr, e_minalloc, e_maxalloc, e_ss, e_sp, e_csum, e_ip, e_cs, e_lfarlc, e_ovno; WORD[4] e_res; WORD e_oemid, e_oeminfo; WORD[10] e_res2; LONG e_lfanew; } alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*; __gshared ubyte[0x800] image; void main() { import std.stdio; import core.stdc.string; auto dosh = cast(PIMAGE_DOS_HEADER)image.ptr; immutable stub = x"b8 01 4c cd 21"; memcpy(&image[IMAGE_DOS_HEADER.sizeof], stub.ptr, stub.length); } Bye, bearophile
Jul 13 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
Oh, thanks a lot!!

With a little change all work!

look:

struct IMAGE_DOS_HEADER {
	WORD e_magic,
	     e_cblp,

//...

void main() {
	import std.stdio;
	import std.file;
	import core.stdc.string;
	
	auto dosh = cast(PIMAGE_DOS_HEADER)image.ptr;
	dosh.e_magic = ('Z' << 8) + 'M';

	immutable stub = x"b8 01 4c cd 21";
	memcpy(&image[IMAGE_DOS_HEADER.sizeof],stub.ptr, stub.length);

	std.file.write("a.exe", image);
}
Jul 13 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
Look at line 114 of my code: http://dpaste.com/3B5WYGV

Have a more better way to make this conversion ?
*(DWORD*)"PE\0\0" ?
Jul 14 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
And some other strange thing is, the generate struct in PE file 
is wrong.. look at imagens...

As it should be...: http://i.imgur.com/4z1T3jF.png

And how is being generated...: http://i.imgur.com/Oysokuh.png

My actual source is that: http://dpaste.com/2TZKWF5

On Monday, 14 July 2014 at 11:55:18 UTC, Alexandre wrote:
 Look at line 114 of my code: http://dpaste.com/3B5WYGV

 Have a more better way to make this conversion ?
 *(DWORD*)"PE\0\0" ?
Jul 14 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 Look at line 114 of my code: http://dpaste.com/3B5WYGV
The indentations are messed up.
 peh.Signature = ('\0' << 8) + ('\0' << 8) + ('E' << 8) + 'P';
You need shifts 8, 16, 24...
 alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*;
I don't see much need for such aliases.
	auto peh = cast(PIMAGE_NT_HEADERS32)&image[0x80];
I suggest to avoid magic constants like that 0x80, like I have avoided it here: memcpy(&image[IMAGE_DOS_HEADER.sizeof], Bye, bearophile
Jul 14 2014
next sibling parent reply "Andrea Fontana" <nospam example.com> writes:
Is there any counter-indication with this:

immutable ubyte[5] stub = x"b8 01 4c cd 21".representation;

?

Is it a compile time value?


On Monday, 14 July 2014 at 12:18:20 UTC, bearophile wrote:
 Alexandre:

 Look at line 114 of my code: http://dpaste.com/3B5WYGV
The indentations are messed up.
 peh.Signature = ('\0' << 8) + ('\0' << 8) + ('E' << 8) + 'P';
You need shifts 8, 16, 24...
 alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*;
I don't see much need for such aliases.
	auto peh = cast(PIMAGE_NT_HEADERS32)&image[0x80];
I suggest to avoid magic constants like that 0x80, like I have avoided it here: memcpy(&image[IMAGE_DOS_HEADER.sizeof], Bye, bearophile
Jul 14 2014
next sibling parent "Alexandre" <alebencz gmail.com> writes:
 immutable ubyte[5] stub = x"b8 01 4c cd 21".representation;
that is a Real-Mode Stub Program On Monday, 14 July 2014 at 12:32:38 UTC, Andrea Fontana wrote:
 Is there any counter-indication with this:

 immutable ubyte[5] stub = x"b8 01 4c cd 21".representation;

 ?

 Is it a compile time value?


 On Monday, 14 July 2014 at 12:18:20 UTC, bearophile wrote:
 Alexandre:

 Look at line 114 of my code: http://dpaste.com/3B5WYGV
The indentations are messed up.
 peh.Signature = ('\0' << 8) + ('\0' << 8) + ('E' << 8) + 'P';
You need shifts 8, 16, 24...
 alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*;
I don't see much need for such aliases.
	auto peh = cast(PIMAGE_NT_HEADERS32)&image[0x80];
I suggest to avoid magic constants like that 0x80, like I have avoided it here: memcpy(&image[IMAGE_DOS_HEADER.sizeof], Bye, bearophile
Jul 14 2014
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Andrea Fontana:

 Is there any counter-indication with this:

 immutable ubyte[5] stub = x"b8 01 4c cd 21".representation;

 ?
See: https://issues.dlang.org/show_bug.cgi?id=10454 https://issues.dlang.org/show_bug.cgi?id=5909
 Is it a compile time value?
Generally you need module-level values or enums to be sure a value is compile-time. In this case it is probably not. Bye, bearophile
Jul 14 2014
prev sibling parent reply "Alexandre" <alebencz gmail.com> writes:
 I don't see much need for such aliases.
Ok, how I can reduce the number of aliaSs ?
 I suggest to avoid magic constants like that 0x80, like I have 
 avoided it here:
 memcpy(&image[IMAGE_DOS_HEADER.sizeof],
Btw, I need to start that part of code in x80 Look, that is my C++ code base: http://dpaste.com/1MMZK4R I get a lot of problens, to convert 'strings' to UCHAR... :/
Jul 14 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 I get a lot of problens, to convert 'strings' to UCHAR... :/
I suggest you to take a look at the D docs and understand what D fixed-sized arrays are, dynamic arrays, and strings (that are dynamic arrays). Bye, bearophile
Jul 14 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
bearophile, Thanks for all help!


"tricks" of D language...
'm reading this book: http://ddili.org/ders/d.en/

I have a struct with union...
struct IMAGE_SECTION_HEADER
{
	BYTE[8] Name;
	union Misc
	{
		DWORD PhysicalAddress,
			VirtualSize;
	}
	DWORD VirtualAddress,
		SizeOfRawData,
		PointerToRawData,
		PointerToRelocations,
		PointerToLinenumbers;
	WORD NumberOfRelocations,
		NumberOfLinenumbers;
	DWORD Characteristics;
}

( the  identation is wrong here... )
Btw, my problem is, how to acess the union elements ?

I try this:
//...
	scth[0].Misc.VirtualSize = 15;
//...

But, the compiler return that error:
main.d(151): Error: need 'this' for 'VirtualSize' of type 'uint'

On Monday, 14 July 2014 at 13:00:21 UTC, bearophile wrote:
 Alexandre:

 I get a lot of problens, to convert 'strings' to UCHAR... :/
I suggest you to take a look at the D docs and understand what D fixed-sized arrays are, dynamic arrays, and strings (that are dynamic arrays). Bye, bearophile
Jul 14 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 	BYTE[8] Name;
Generally in D field names start with a lowercase (unless you need them with uppercase).
 Btw, my problem is, how to acess the union elements ?

 I try this:
 //...
 	scth[0].Misc.VirtualSize = 15;
 //...

 But, the compiler return that error:
 main.d(151): Error: need 'this' for 'VirtualSize' of type 'uint'
The error message is not the best. It is saying you are not accessing data, just its definition. So you need to instantiate the union: struct Foo { ubyte[8] name; union Bar { ushort physicalAddress, virtualSize; } Bar b; } void main() { Foo f; f.b.physicalAddress = 10; } Or use an anonymous one: struct Foo { ubyte[8] name; union { ushort physicalAddress, virtualSize; } } void main() { Foo f; f.physicalAddress = 10; } Bye, bearophile
Jul 14 2014
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
 Generally in D field names start with a lowercase (unless you 
 need them with uppercase).
And user defined type names start with an upper case. This is useful, because if you write: scth[0].Misc.virtualSize = 15; You see immediately that Misc is not a value but a type. So it can't work. Bye, bearophile
Jul 14 2014
prev sibling parent reply "Alexandre" <alebencz gmail.com> writes:
Yes yes, I did it, I used the anonymous type

Look the complete code: 
https://gist.github.com/bencz/3576dfc8a217a34c05a9

I know, has several things that can be improved
Jul 14 2014
next sibling parent reply "Jason King" <jhking airmail.net> writes:
On Monday, 14 July 2014 at 14:50:36 UTC, Alexandre wrote:
 Yes yes, I did it, I used the anonymous type

 Look the complete code: 
 https://gist.github.com/bencz/3576dfc8a217a34c05a9

 I know, has several things that can be improved
Now that you've done that, can you build us a linker that reads COFF libs so we can lose optlink:)
Jul 14 2014
parent "Alexandre" <alebencz gmail.com> writes:
Soory, I not understand, why lose the optlink ?
Read the libs is simple, but, the linker do the brute force!

On Monday, 14 July 2014 at 15:17:06 UTC, Jason King wrote:
 On Monday, 14 July 2014 at 14:50:36 UTC, Alexandre wrote:
 Yes yes, I did it, I used the anonymous type

 Look the complete code: 
 https://gist.github.com/bencz/3576dfc8a217a34c05a9

 I know, has several things that can be improved
Now that you've done that, can you build us a linker that reads COFF libs so we can lose optlink:)
Jul 14 2014
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 Look the complete code: 
 https://gist.github.com/bencz/3576dfc8a217a34c05a9

 I know, has several things that can be improved
memcpy(&dosh.e_magic, "MZ".ptr, 2); memcpy(&peh.Signature, "PE\0\0".ptr, 4); memcpy(scth[1].Name.ptr, ".idata".ptr, 6); memcpy(scth[2].Name.ptr, ".data".ptr, 5); memcpy(&image[0x428], x"3820".ptr, 2); memcpy(&image[0x430], x"3820".ptr, 2); memcpy(&image[0x43a], "printf".ptr, 6); memcpy(&image[0x448], "msvcrt.dll".ptr, 10); memcpy(&image[0x201], x"00304000".ptr, 4); memcpy(&image[0x207], x"30204000".ptr, 4); memcpy(&image[0x600], "hello\n".ptr, 6); Instead of this very bug-prone code, write yourself a little function to perform this more safely. Bye, bearophile
Jul 14 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
void InjectData(T)(ref T BaseSrc, string data)
{
	memcpy(&BaseSrc, data.ptr, data.length);
}

It's possible to improve this function ?

On Monday, 14 July 2014 at 15:45:19 UTC, bearophile wrote:
 Alexandre:

 Look the complete code: 
 https://gist.github.com/bencz/3576dfc8a217a34c05a9

 I know, has several things that can be improved
memcpy(&dosh.e_magic, "MZ".ptr, 2); memcpy(&peh.Signature, "PE\0\0".ptr, 4); memcpy(scth[1].Name.ptr, ".idata".ptr, 6); memcpy(scth[2].Name.ptr, ".data".ptr, 5); memcpy(&image[0x428], x"3820".ptr, 2); memcpy(&image[0x430], x"3820".ptr, 2); memcpy(&image[0x43a], "printf".ptr, 6); memcpy(&image[0x448], "msvcrt.dll".ptr, 10); memcpy(&image[0x201], x"00304000".ptr, 4); memcpy(&image[0x207], x"30204000".ptr, 4); memcpy(&image[0x600], "hello\n".ptr, 6); Instead of this very bug-prone code, write yourself a little function to perform this more safely. Bye, bearophile
Jul 14 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 void InjectData(T)(ref T BaseSrc, string data)
 {
 	memcpy(&BaseSrc, data.ptr, data.length);
 }

 It's possible to improve this function ?
You can add some modifiers (like nogc for dmd 2.066), and the name of D functions starts with a lower case. Bye, bearophile
Jul 14 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
I have this struct:

enum AddrType { Abs, RVA, Rel };
struct Address
{
     shared_ptr<DWORD> addr;
     AddrType type;

     Address(): type(Abs) {}
     Address(DWORD addr, AddrType type):
         addr(shared_ptr<DWORD>(new DWORD(addr))), type(type) {}
     Address(shared_ptr<DWORD> addr, AddrType type):
         addr(addr), type(type) {}
     Address(const Address &ad):
         addr(ad.addr), type(ad.type) {}
};

My problem is with default alue init...
Address(): type(Abs) {}
Address(DWORD addr, AddrType type):
         addr(shared_ptr<DWORD>(new DWORD(addr))), type(type) {}

How to make this in D ?
I do this:

struct Address
{
	RefCounted!(DWORD) addr;
	AddrType type = AddrType.Abs;
	this(DWORD addr, AddrType type)
	{
		addr(RefCounted!(DWORD)(new DWORD(addr)));
		this.type = type;
	}
	/*Address(shared_ptr<DWORD> addr, AddrType type) :
	addr(addr), type(type) {}
	Address(const Address &ad) :
	addr(ad.addr), type(ad.type) {}*/
};

It's correct ?


In case for a template, when I have this:
template <typename T> struct Wrap {
     T val;
     Wrap(T val): val(val) {}
};

I maded this:
template Wrap(T)
{
	struct Wrap
	{
		T val;
		this(T val){val = val;}
	}
}

PS: ( I know about identation... it's wrong here... )
Jul 15 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 	RefCounted!(DWORD) addr;
I think RefCounted is for advanced usages in D :-)
 template Wrap(T)
 {
 	struct Wrap
 	{
 		T val;
 		this(T val){val = val;}
 	}
 }
Simpler: struct Wrap(T) { T val; this(T val_) { this.val = val_; } } Or just: struct Wrap(T) { T val; } Bye, bearophile
Jul 15 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
Oh!
I used the RefCounted because this:
"The proposed C++ shared_ptr<>, which implements ref counting, 
suffers from all these faults. I haven't seen a heads up 
benchmark of shared_ptr<> vs mark/sweep, but I wouldn't be 
surprised if shared_ptr<> turned out to be a significant loser in 
terms of both performance and memory consumption.

That said, D may in the future optionally support some form of 
ref counting, as rc is better for managing scarce resources like 
file handles. Furthermore, if ref counting is a must, Phobos has 
the std.typecons.RefCounted type which implements it as a 
library, similar to C++'s shared_ptr<>."

I found that in this link: 
http://dlang.org/faq.html#reference-counting

On Tuesday, 15 July 2014 at 14:46:01 UTC, bearophile wrote:
 Alexandre:

 	RefCounted!(DWORD) addr;
I think RefCounted is for advanced usages in D :-)
 template Wrap(T)
 {
 	struct Wrap
 	{
 		T val;
 		this(T val){val = val;}
 	}
 }
Simpler: struct Wrap(T) { T val; this(T val_) { this.val = val_; } } Or just: struct Wrap(T) { T val; } Bye, bearophile
Jul 15 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 as rc is better for managing scarce resources like file handles.
File instances are ref counted in D. Is this useful for you? Bye, bearophile
Jul 15 2014
parent reply "Alexandre" <alebencz gmail.com> writes:
Yes yes, I will use the ref... is more safer!

I will try to re-create my logic...
btw, how is the best way to "reinterpret" this ??:

map<string, Address> syms;

and:
vector<pair<DWORD, Address>> values;
vector<pair<DWORD, shared_ptr<DWORD>>> addrs;

On Tuesday, 15 July 2014 at 14:55:36 UTC, bearophile wrote:
 Alexandre:

 as rc is better for managing scarce resources like file 
 handles.
File instances are ref counted in D. Is this useful for you? Bye, bearophile
Jul 15 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Alexandre:

 map<string, Address> syms;
If you don't need the key ordering then use a built-in associative array: Address[string] syms; Otherwise use a RedBlackTree from std.container.
 vector<pair<DWORD, Address>> values;
 vector<pair<DWORD, shared_ptr<DWORD>>> addrs;
Tuple!(DWORD, Address)[] values; Tuple!(DWORD, DWORD*)[] addrs; Tuple and tuple are in std.typecons. Bye, bearophile
Jul 15 2014
parent reply "Meta" <jared771 gmail.com> writes:
On Tuesday, 15 July 2014 at 16:04:26 UTC, bearophile wrote:
 Alexandre:

 map<string, Address> syms;
If you don't need the key ordering then use a built-in associative array: Address[string] syms; Otherwise use a RedBlackTree from std.container.
 vector<pair<DWORD, Address>> values;
 vector<pair<DWORD, shared_ptr<DWORD>>> addrs;
Tuple!(DWORD, Address)[] values; Tuple!(DWORD, DWORD*)[] addrs; Tuple and tuple are in std.typecons. Bye, bearophile
For `Tuple!(DWORD, DWORD*)[] addrs;`, DWORD* is not same as shared_ptr<DWORD>. It's important to keep that in mind.
Jul 17 2014
parent reply " bearophile" < bearophileHUGS lycos.com> writes:
Meta:

 For `Tuple!(DWORD, DWORD*)[] addrs;`, DWORD* is not same as 
 shared_ptr<DWORD>. It's important to keep that in mind.
OK. How do you suggest to translate it in D? Bye, bearophile
Jul 17 2014
parent "Meta" <jared771 gmail.com> writes:
On Thursday, 17 July 2014 at 13:40:20 UTC, bearophile wrote:
 Meta:

 For `Tuple!(DWORD, DWORD*)[] addrs;`, DWORD* is not same as 
 shared_ptr<DWORD>. It's important to keep that in mind.
OK. How do you suggest to translate it in D? Bye, bearophile
I don't know. I just wanted to make sure OP knew that raw pointers in D are not analogous to C++ shared_ptr.
Jul 17 2014
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/15/2014 07:40 AM, Alexandre wrote:

 I have this struct:
I think many short discussion threads are more efficient than a single long thread. Many different C++ and D concepts are making this thread difficult to follow for me. :) Ali
Jul 15 2014