Most convenient way to write a loop with fixed length and no need for the index?
What do I have to do, to make this work? iota(number).each!...command_x(a...);command_y(b...);command_z(c..)) ^? how to write the lambda? Similar to the ruby (1..number).each{ commands...} Don't want to write the following, because the index i is not used inside the loop and this should be clear when reading it: for (i=0;i
Re: mysql-native + vibe.d example
On Friday, 30 June 2017 at 00:52:28 UTC, crimaniak wrote: Hi! Moving my project from mysql-lited to mysql-native I faced the problem with null pointer error inside of mysql-native: [...] It seems I am doing something wrong so myself-native fails to detect it in isValid(). So I search for example how to use mysql-native in real multi-threaded vibe.d application with usage of MySQLPool. Please do not point me to basic example provided with package because it is single thread. Thanks. Sorry, can not help, but would be very interested to learn how to do a real multi-threaded vibe.d with mysql So if you find a solution, please make an simplified example for vibe.d documentation! Sönke might include it into vibe.d docs.
Re: Most convenient way to write a loop with fixed length and no need for the index?
On 06/30/2017 12:44 AM, Martin Tschierschke wrote: What do I have to do, to make this work? iota(number).each!...command_x(a...);command_y(b...);command_z(c..)) ^? how to write the lambda? Similar to the ruby (1..number).each{ commands...} Don't want to write the following, because the index i is not used inside the loop and this should be clear when reading it: for (i=0;i Seems easy to put together: :) import std.stdio; auto times(alias Func, T)(T number) { import std.range : iota; import std.algorithm : each; return number.iota.each!(_ => Func()); } void foo() { writeln("foo"); } void bar() { writeln("bar"); } void main() { 3.times!({ foo(); bar(); }); } Ali
Re: Most convenient way to write a loop with fixed length and no need for the index?
On Friday, 30 June 2017 at 07:44:45 UTC, Martin Tschierschke wrote: What do I have to do, to make this work? iota(number).each!...command_x(a...);command_y(b...);command_z(c..)) ^? how to write the lambda? Similar to the ruby (1..number).each{ commands...} Don't want to write the following, because the index i is not used inside the loop and this should be clear when reading it: for (i=0;i You can use it like this: iota(10).each!((x) { command1(); command2(); ... }); Or there is a short syntax (lambda): iota(10).each!((x) => command1()); See http://dlang.org/spec/expression.html#Lambda for more info about lambdas. Or is there something like number.times!{} possible? You can write your own function. It is simple. void times(alias fun)(size_t i) { foreach(unused;0..i) fun(); } and use it like this: 10.times!({ writeln("yaaay"); });
Re: How to partially apply member functions?
On Thursday, 29 June 2017 at 14:30:19 UTC, Andrea Fontana wrote: On Thursday, 29 June 2017 at 13:01:10 UTC, ct wrote: I was only able to do it this way: auto on_next_previous = &this.OnNextPreviousMatch; entry_.addOnNextMatch(&partial!(on_next_previous, true)); entry_.addOnPreviousMatch(&partial!(on_next_previous, false)); I think you should provide a better example in order to get some help. We neither know what argument .addOnNextMatch() expects. Usually a full example on https://dpaste.dzfl.pl or other websites is more useful :) Andrea Sorry. Please check this DPaste: https://dpaste.dzfl.pl/6379944510b8 addOnNextMatch() is gtk.SearchEntry.addOnNextMatch() [https://api.gtkd.org/gtkd/gtk/SearchEntry.html] which has the signature: gulong addOnNextMatch (void delegate(SearchEntry) dlg, ConnectFlags connectFlags = cast(ConnectFlags)0); So basically, it needs a void delegate(SearchEntry) as an argument. I wanted to create a single callback member function to handle both addOnNextMatch() and addOnPreviousMatch() by binding a bool value (true for next_match, false for previous_match) so that the callback knows which case it is handling. It compiled when I wrote: auto on_next_previous = &this.OnNextPreviousMatch; entry_.addOnNextMatch(&partial!(on_next_previous, true)); entry_.addOnPreviousMatch(&partial!(on_next_previous, false)); But not when I wrote: entry_.addOnNextMatch(partial!(&this.OnNextPreviousMatch, true)); Or entry_.addOnNextMatch(partial!(&Editor.OnNextPreviousMatch, true)); Error: value of 'this' is not known at compile time
Re: Force usage of double (instead of higher precision)
On Thursday, 29 June 2017 at 12:00:53 UTC, Simon Bürger wrote: Thanks a lot for your comments. On Wednesday, 28 June 2017 at 23:56:42 UTC, Stefan Koch wrote: [...] This is only happening on CTFE ? Enforcing to use the old 8086 FPU for any float/double operation would give a lot performance penalty on any modern CPU.
Strange Bug in LDC vs DMD
I am using dirEntries to iterate over files to rename them. I am renaming them in a loop(will change but added code for testing). In DMD the renaming works but in LDC the renaming fails. It fails in a way that I can't quite tell and I cannot debug because visual D is not working properly for LDC. The code essentially look like the following: auto dFiles = dirEntries(loc, mask, _mode); foreach (d; dFiles) { auto newName = Recompute(d.name) writeln(newName); rename(d.name, newName); } but when I comment out rename, it works under LDC. The funny thing is, newName is printed wrong so Recompute is effected by the rename. This shouldn't occur. Now, dirEntries is a range, so I'm curious if the recomputation is occurring after the rename(if it did then the recomputation would be invalid and produce the results it is producing)? When I forcably convert dirEntries in to an array(manually, unfortunately, as I can't seem to use array() on dirEntries), everything works). struct file { public string name; } auto dFiles = dirEntries(loc, mask, _mode); file[] files; foreach (d; dFiles) { file f; f.name = d.name; files ~= f; } foreach (d; files) { auto newName = Recompute(d.name) writeln(newName); rename(d.name, newName); } While it works, the main issue is that a different behavior is observed between DMD and LDC in the first case. It would be nice to know how to simplify the code though so "lazy" evaluation of dirEntries did not occur.
Re: Strange Bug in LDC vs DMD
On Friday, 30 June 2017 at 12:50:24 UTC, FoxyBrown wrote: The funny thing is, newName is printed wrong so Recompute is effected by the rename. Does LDC use Unicode? Or, maybe, standard library under LDC does not support Unicode - then it is a serious bug. Do you use any non-ASCII symbols? Maybe, the Recompute() function returns a non-unicode string under LDC?
Re: Strange Bug in LDC vs DMD
On Friday, 30 June 2017 at 15:07:29 UTC, Murzistor wrote: On Friday, 30 June 2017 at 12:50:24 UTC, FoxyBrown wrote: The funny thing is, newName is printed wrong so Recompute is effected by the rename. Does LDC use Unicode? Or, maybe, standard library under LDC does not support Unicode - then it is a serious bug. Do you use any non-ASCII symbols? Maybe, the Recompute() function returns a non-unicode string under LDC? None of these reasons make sense. They do not take in to account that simply pre-evaluating dirEntries causes it to work nor the fact that I said that commenting the rename out also works.
Re: mysql-native + vibe.d example
On Friday, 30 June 2017 at 00:52:28 UTC, crimaniak wrote: Hi! Moving my project from mysql-lited to mysql-native I faced the problem with null pointer error inside of mysql-native: seems like it's already fixed https://github.com/mysql-d/mysql-native/commit/477636ad92a15d504308d1893f987685cd71
Re: Force usage of double (instead of higher precision)
On Friday, 30 June 2017 at 11:42:39 UTC, Luis wrote: On Thursday, 29 June 2017 at 12:00:53 UTC, Simon Bürger wrote: Thanks a lot for your comments. On Wednesday, 28 June 2017 at 23:56:42 UTC, Stefan Koch wrote: [...] This is only happening on CTFE ? Enforcing to use the old 8086 FPU for any float/double operation would give a lot performance penalty on any modern CPU. CTFE only (incl. parsing of literals). Just make sure you don't happen to call a std.math function only accepting reals; I don't know how many of those are still around.
Re: Force usage of double (instead of higher precision)
On Friday, 30 June 2017 at 16:21:18 UTC, kinke wrote: CTFE only (incl. parsing of literals). Just make sure you don't happen to call a std.math function only accepting reals; I don't know how many of those are still around. Oh, apparently most still are. There are even some mean overloads for double/float only casting and forwarding to the `real` implementation.
Get Function Body
Is there a way to retrieve the body of a function as a string? Scenario. I want to pass a function to a mixin template and just mixin the body of the function. Ex. mixin template Foo(alias fun) { void bar() { mixin(getBodyOfFun(fun)); } } I'm aware that I can pass a string like mixin Foo!"a > b" but I would really like to avoid that. I also can't just call "fun" as normal, unless it can be forced to be inline within the mixin template. The reason is if I mixin two mixin templates with the same function passed it must exist as two different function bodies executed, even tho they do the same. Which means the following must have two "different" baz and not the actual baz. void baz() { ... } mixin Foo!baz; mixin Foo!baz; I don't know if it'll be possible without some sort of "parsing" the function or even without "string function bodies".
Re: Force usage of double (instead of higher precision)
On Friday, 30 June 2017 at 16:29:22 UTC, kinke wrote: On Friday, 30 June 2017 at 16:21:18 UTC, kinke wrote: CTFE only (incl. parsing of literals). Just make sure you don't happen to call a std.math function only accepting reals; I don't know how many of those are still around. Oh, apparently most still are. There are even some mean overloads for double/float only casting and forwarding to the `real` implementation. That is not a problem. The only problem is that the excess is not discarded at the end. Which is because of the design of the constant-folder.
Re: Get Function Body
On Friday, 30 June 2017 at 16:38:45 UTC, bauss wrote: Is there a way to retrieve the body of a function as a string? Scenario. I want to pass a function to a mixin template and just mixin the body of the function. Ex. mixin template Foo(alias fun) { void bar() { mixin(getBodyOfFun(fun)); } } I'm aware that I can pass a string like mixin Foo!"a > b" but I would really like to avoid that. I also can't just call "fun" as normal, unless it can be forced to be inline within the mixin template. The reason is if I mixin two mixin templates with the same function passed it must exist as two different function bodies executed, even tho they do the same. Which means the following must have two "different" baz and not the actual baz. void baz() { ... } mixin Foo!baz; mixin Foo!baz; I don't know if it'll be possible without some sort of "parsing" the function or even without "string function bodies". You need to function body as a string. There is no way of retriving a functionBodyString from the compiler. And I suspect it would be a bad idea to be able to do so. Since the compiler may mutate the body while processing/optimizing.
Re: Get Function Body
On Friday, 30 June 2017 at 16:43:33 UTC, Stefan Koch wrote: On Friday, 30 June 2017 at 16:38:45 UTC, bauss wrote: Is there a way to retrieve the body of a function as a string? Scenario. I want to pass a function to a mixin template and just mixin the body of the function. Ex. mixin template Foo(alias fun) { void bar() { mixin(getBodyOfFun(fun)); } } I'm aware that I can pass a string like mixin Foo!"a > b" but I would really like to avoid that. I also can't just call "fun" as normal, unless it can be forced to be inline within the mixin template. The reason is if I mixin two mixin templates with the same function passed it must exist as two different function bodies executed, even tho they do the same. Which means the following must have two "different" baz and not the actual baz. void baz() { ... } mixin Foo!baz; mixin Foo!baz; I don't know if it'll be possible without some sort of "parsing" the function or even without "string function bodies". You need to function body as a string. There is no way of retriving a functionBodyString from the compiler. And I suspect it would be a bad idea to be able to do so. Since the compiler may mutate the body while processing/optimizing. Well in my case I don't want optimization or anything like that, in fact the original function wouldn't matter at all. I guess I'll go with the string way then though. I'm aware this is probably not a scenario day-to-day code will need, but in my case I need to make my program as obscure as possible.
Re: Strange Bug in LDC vs DMD
On Fri, Jun 30, 2017 at 12:50:24PM +, FoxyBrown via Digitalmars-d-learn wrote: > I am using dirEntries to iterate over files to rename them. > > I am renaming them in a loop(will change but added code for testing). > > > In DMD the renaming works but in LDC the renaming fails. It fails in a > way that I can't quite tell and I cannot debug because visual D is not > working properly for LDC. > > The code essentially look like the following: > > > auto dFiles = dirEntries(loc, mask, _mode); > > foreach (d; dFiles) > { > >auto newName = Recompute(d.name) >writeln(newName); >rename(d.name, newName); > } > > but when I comment out rename, it works under LDC. > > The funny thing is, newName is printed wrong so Recompute is effected > by the rename. > > This shouldn't occur. [...] This sounds very strange. What exactly do you mean by "newName is printed wrong"? Do you mean that somehow it's getting affected by the *subsequent* rename()? That would be truly strange. Or do you mean that newName doesn't match what you expect Recompute to do given d.name? Perhaps you should also print out d.name along with newName just to be sure? Do you have a reduced code example that's compilable/runnable? It's rather hard to tell what's wrong based on your incomplete snippet. T -- An imaginary friend squared is a real enemy.
Re: Force usage of double (instead of higher precision)
On Friday, 30 June 2017 at 16:39:16 UTC, Stefan Koch wrote: On Friday, 30 June 2017 at 16:29:22 UTC, kinke wrote: On Friday, 30 June 2017 at 16:21:18 UTC, kinke wrote: CTFE only (incl. parsing of literals). Just make sure you don't happen to call a std.math function only accepting reals; I don't know how many of those are still around. Oh, apparently most still are. There are even some mean overloads for double/float only casting and forwarding to the `real` implementation. That is not a problem. The only problem is that the excess is not discarded at the end. Which is because of the design of the constant-folder. I was referring to runtime performance, as that was what Luis was concerned about.
Re: How to partially apply member functions?
On 06/30/2017 01:43 AM, ct wrote: > entry_.addOnNextMatch(partial!(&this.OnNextPreviousMatch, true)); Just to note, member function pointers are delegates in D, which combines the 'this' pointer of the object and a context pointer. Since the object is available at run time, such a delegate cannot be used as a template parameter. partial is designed to work with free standing functions. It uses the second template argument as the first parameter to the function. So, there is no consideration for member function calls. Perhaps partial can be improved to handle that case but I don't know whether the 'this' pointer can be added to the delegate easily or at all. Ali
Re: Strange Bug in LDC vs DMD
On Friday, 30 June 2017 at 17:32:33 UTC, H. S. Teoh wrote: On Fri, Jun 30, 2017 at 12:50:24PM +, FoxyBrown via Digitalmars-d-learn wrote: I am using dirEntries to iterate over files to rename them. I am renaming them in a loop(will change but added code for testing). In DMD the renaming works but in LDC the renaming fails. It fails in a way that I can't quite tell and I cannot debug because visual D is not working properly for LDC. The code essentially look like the following: auto dFiles = dirEntries(loc, mask, _mode); foreach (d; dFiles) { auto newName = Recompute(d.name) writeln(newName); rename(d.name, newName); } but when I comment out rename, it works under LDC. The funny thing is, newName is printed wrong so Recompute is effected by the rename. This shouldn't occur. [...] This sounds very strange. What exactly do you mean by "newName is printed wrong"? Do you mean that somehow it's getting affected by the *subsequent* rename()? That would be truly strange. Or do you mean that newName doesn't match what you expect Recompute to do given d.name? Perhaps you should also print out d.name along with newName just to be sure? Do you have a reduced code example that's compilable/runnable? It's rather hard to tell what's wrong based on your incomplete snippet. T No, if I simply comment out the rename line, then the writeln output changes. Simple as that. No other logic changes in the code. This means that the rename is affecting the output. The recompute code gets the filename, does a computation on it, then returns it.. prints it out, then renames that file to the newly computed file name. The only way this can happen is if the rename command is somehow feeding back in to the algorithm. Since the problem goes away when I pre-compute dirEntries, it suggests that dirEntries is being lazily computed. If that is the case, then the problem is easily understood: The file gets renamed, dirEntries reiterates over the file, then it gets recomputed again, but this time the result is bogus because it is a double recompute, which is meaningless in this program. I'm pretty sure that the analysis above is correct, that is, dirEntries is lazy and ends up picking up the renamed file. This is sort of like removing an element in an array while iterating over the array. The odd thing is, is that DMD does not produce the same result. I do not know if there is a different in the LDC vs DMD dirEntries code(or lazily evaluated code in general) or if it has to do with speed(possibly the renames are cached and do not show up immediately to dirEntries with the slower DMD?). I do not have any simplified code and I'm moving on from here. It should be easy to mock something up. The main thing to do is to rename the files based on something in the file name. e.g., suppose you have the files 1,2,3,4,5 (that is there names) and extract and multiply the filenames by 10. (that is your recompute function). You should end up with 10,20,30,40,50. But if the cause of issue I'm describing is in fact true, one don't necessarily get that because some files will be iterated more than once. e.g., maybe 10, 100, 1000, 20, 200, 30, 40, 50, 500. I am doing it over a lot of files btw, but that is essentially what is going on. The example above should be easy to do since one can simply to!int the filename and then multiply it by 10 and then rename that. I have moved on to avoid dirEntries completely and simply use the os directory listing function manually to extract the data but this should be investigated as it if it the behavior is what I am describing, a serious bug exists somewhere. (if someone could confirm that dirEntries is a lazy range, then it would explain the problem, but not necessarily why dmd and ldc differ, (dmd seeming to function as expected)).
Natural Sort optimzation
Spent the last hour trying to get a natural sort. Ended up having to create my own(not sure if it's 100% correct though but works in practice). The Rosetta one is not correct. Here is my implementation, anyone care to perfect it? // Compares the strings a and b numerically, e.g., "04038284" and "02" returns 1, the first is larger. int compareStringNum(string a, string b) { // Remove leading 0's a = a.stripLeft('0'); b = b.stripLeft('0'); if (a.length > b.length) return 1; if (a.length < b.length) return -1; auto m = a.length; for(int i = 0; i < m; i++) { auto qqx = a[i]; auto qqy = b[i]; // Assume ascii comparision holds, i.e., '0' < '1' < ... < '9' if (a[i] > b[i]) return 1; if (a[i] < b[i]) return -1; } return 0; } string[] naturalSort(string[] arr) /*pure @safe*/ { alias myComp = (x, y) { auto ml = min(x.length, y.length)-1; auto ofsx = -1; auto ofsy = -1; auto numx_found = -1; auto numy_found = -1; for(int i = 0; i < ml; i++) { ofsx++; ofsy++; // If we have not found any numbers(that are not the same) and we have a difference, the strings must be different, fall back on standard character comparer if (!isDigit(x[ofsx]) && !isDigit(y[ofsy]) && x[ofsx] != y[ofsy] && numx_found < 0 && numy_found < 0) return x[ofsx] > y[ofsy]; // We are at a position in the string where either we are at the end of a digit sequence or the characters have been identical up to this point if (isDigit(x[ofsx]) && numx_found < 0) numx_found = ofsx; if (isDigit(y[ofsy]) && numy_found < 0) numy_found = ofsy; if (!isDigit(x[ofsx]) && !isDigit(y[ofsy]) && numx_found >= 0 && numy_found >= 0) { auto numx = x[numx_found..ofsx]; auto numy = y[numy_found..ofsy]; auto res = compareStringNum(numx, numy); if (res != 0) return (res != 1); } if (!isDigit(x[ofsx]) && !isDigit(y[ofsy])) { numx_found = -1; numy_found = -1; } else { if (!isDigit(x[ofsx]) && numx_found >= 0) ofsx--; if (!isDigit(y[ofsy]) && numy_found >= 0) ofsy--; } } return x > y; }; auto x = arr.sort!(myComp).release; return x; }
ReadProcessMemory + address from ollydbg
I'm currently getting garbage data when using ReadProcessMemory to read from another process. This is my definition: BOOL ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead); And I'm reading it like this: if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, cast(DWORD)stringSize, cast(PDWORD)&bytesRead)) { return defaultValue; } process is a HANDLE that I got from OpenProcess() address is a DWORD data is char[1024] stringSize is size_t bytesRead is PDWORD The address I obtained was from Ollydbg and it's a static address. I'm not sure if I however need some kind of offset etc. I tried to search and found you might have to use GetModuleHandleA() but I tried that and I still get garbage data with the offset from that. What am I doing wrong?
Re: Strange Bug in LDC vs DMD
On Fri, Jun 30, 2017 at 07:57:22PM +, FoxyBrown via Digitalmars-d-learn wrote: [...] > The only way this can happen is if the rename command is somehow > feeding back in to the algorithm. Since the problem goes away when I > pre-compute dirEntries, it suggests that dirEntries is being lazily > computed. Um... the docs explicit say that dirEntries is lazy, did you not see that? https://dlang.org/phobos/std_file#dirEntries "Returns an input range of DirEntry that *lazily* iterates a given directory, ..." [emphasis mine] [...] > I'm pretty sure that the analysis above is correct, that is, > dirEntries is lazy and ends up picking up the renamed file. This is > sort of like removing an element in an array while iterating over the > array. This is certainly what it looks like; however, it doesn't explain a couple of things: 1) Why the DMD version appears to be unaffected, since as far as I can tell from the code, it is also a lazy iteration; 2) On Linux at least, renaming a file does not move the location of the entry in the directory, so whether dirEntries is lazy or not shouldn't even matter in the first place. Does Windows reorder the directory when you rename files? E.g., if you set the folder to sort alphabetically, does it actually sort the directory, or does it only sort the GUI output? My guess is that the sort order only affects the GUI output, as it would be grossly inefficient to actually sort the directory. But you never know with Windows... In any case, if Windows *does* physically sort the folder, that could explain how rename() affects dirEntries. However, this still doesn't explain the discrepancy between DMD and LDC. Actually, now that I think of it... Linux may do the same thing if the new filename is longer and doesn't fit in the old slot. So that could explain (2). However, why the difference between DMD and LDC? It doesn't make sense to me, if you tested both on the same OS. Here's a way to rule out (2): instead of using the current working directory, change the code to create a fresh copy of the directory each time. Does DMD / LDC still show a difference? The idea here is that it may have been a coincidence that you saw LDC having the problem and DMD not, since whether or not a renamed file gets moved depends on how big the current slot for its name is in the directory, and if you've already done a bunch of operations on the directory, some slots will be bigger and some will be smaller, so some renames will happen in-place whereas others will cause a reordering. It could be you just got unlucky with LDC and caused a reordering, whereas you got lucky with DMD and the existing slots were already big enough so the problem isn't visible. OTOH, this still doesn't explain why calling the OS functions directly fixes the problem. If there is a bug in LDC's version of dirEntries somewhere, we'd like to know about it so that we can fix it. T -- Without outlines, life would be pointless.
Re: ReadProcessMemory + address from ollydbg
On Friday, 30 June 2017 at 20:14:15 UTC, bauss wrote: This is my definition: BOOL ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead); And I'm reading it like this: if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, cast(DWORD)stringSize, cast(PDWORD)&bytesRead)) { return defaultValue; } I guess the first cast is necessary when `address` isn't typed as a pointer yet. But the other casts shouldn't be needed. If you get errors without them, those errors might give a hint on what's wrong. process is a HANDLE that I got from OpenProcess() address is a DWORD data is char[1024] stringSize is size_t bytesRead is PDWORD bytesRead is a SIZE_T, no? Or maybe a DWORD.
Re: Strange Bug in LDC vs DMD
On Friday, 30 June 2017 at 20:13:37 UTC, H. S. Teoh wrote: On Fri, Jun 30, 2017 at 07:57:22PM +, FoxyBrown via Digitalmars-d-learn wrote: [...] [...] Um... the docs explicit say that dirEntries is lazy, did you not see that? [...] It is possible that dmd has the same problem but I did not see it. What I did was develop it using dmd then once it was working went to release ldc and saw that it immediately did not have the same results and the results were wrong. Since I was debugging it the whole time and it was working fine with dmd, I simply assumed dmd was working. Since it is a lazy range, I'm sure that is the problem.
Re: mysql-native + vibe.d example
On Friday, 30 June 2017 at 16:18:33 UTC, tetyys wrote: On Friday, 30 June 2017 at 00:52:28 UTC, crimaniak wrote: Hi! Moving my project from mysql-lited to mysql-native I faced the problem with null pointer error inside of mysql-native: seems like it's already fixed https://github.com/mysql-d/mysql-native/commit/477636ad92a15d504308d1893f987685cd71 Yes, this is relevant fix. Thanks!
Re: ReadProcessMemory + address from ollydbg
On Friday, 30 June 2017 at 21:36:25 UTC, ag0aep6g wrote: On Friday, 30 June 2017 at 20:14:15 UTC, bauss wrote: This is my definition: BOOL ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead); And I'm reading it like this: if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, cast(DWORD)stringSize, cast(PDWORD)&bytesRead)) { return defaultValue; } I guess the first cast is necessary when `address` isn't typed as a pointer yet. But the other casts shouldn't be needed. If you get errors without them, those errors might give a hint on what's wrong. process is a HANDLE that I got from OpenProcess() address is a DWORD data is char[1024] stringSize is size_t bytesRead is PDWORD bytesRead is a SIZE_T, no? Or maybe a DWORD. It's the same. This is my read function: string ReadWinString(HANDLE process, DWORD address, size_t stringSize, string defaultValue = "") { if (!process || !address) { return defaultValue; } SIZE_T bytesRead; char[1024] data; if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, stringSize, &bytesRead)) { return defaultValue; } auto s = cast(string)data[0 .. stringSize]; return s ? s : defaultValue; } And this is how I call it: auto text = ReadWinString(handleFromOpenProcess, 0x000, 16, "defaultString..."); where 0x000 is the address obviously. If you can spot what I'm doing wrong it would be appreciated.
Re: ReadProcessMemory + address from ollydbg
On Friday, 30 June 2017 at 23:41:19 UTC, bauss wrote: On Friday, 30 June 2017 at 21:36:25 UTC, ag0aep6g wrote: On Friday, 30 June 2017 at 20:14:15 UTC, bauss wrote: [...] I guess the first cast is necessary when `address` isn't typed as a pointer yet. But the other casts shouldn't be needed. If you get errors without them, those errors might give a hint on what's wrong. [...] bytesRead is a SIZE_T, no? Or maybe a DWORD. It's the same. This is my read function: string ReadWinString(HANDLE process, DWORD address, size_t stringSize, string defaultValue = "") { if (!process || !address) { return defaultValue; } SIZE_T bytesRead; char[1024] data; if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, stringSize, &bytesRead)) { return defaultValue; } auto s = cast(string)data[0 .. stringSize]; return s ? s : defaultValue; } And this is how I call it: auto text = ReadWinString(handleFromOpenProcess, 0x000, 16, "defaultString..."); where 0x000 is the address obviously. If you can spot what I'm doing wrong it would be appreciated. I mean I get data, it's not like the call fails or gives an error. It's just not the data I'm expecting. I suspect the address is wrong, but it's the static address I picked up from ollydbg, so I'm kinda lost as for how ollydbg can get the correct string and I get the wrong one using same address.
Re: ReadProcessMemory + address from ollydbg
On Friday, 30 June 2017 at 23:53:19 UTC, bauss wrote: I suspect the address is wrong, but it's the static address I picked up from ollydbg, so I'm kinda lost as for how ollydbg can get the correct string and I get the wrong one using same address. You are aware that processes life in different memory spaces ?
Re: ReadProcessMemory + address from ollydbg
On Friday, 30 June 2017 at 23:56:10 UTC, Stefan Koch wrote: On Friday, 30 June 2017 at 23:53:19 UTC, bauss wrote: I suspect the address is wrong, but it's the static address I picked up from ollydbg, so I'm kinda lost as for how ollydbg can get the correct string and I get the wrong one using same address. You are aware that processes life in different memory spaces ? Well it's a static address I'm trying to read from, so it shouldn't matter if I have the write handle to the process and the static address, should it?
Re: ReadProcessMemory + address from ollydbg
On 07/01/2017 01:41 AM, bauss wrote: string ReadWinString(HANDLE process, DWORD address, size_t stringSize, string defaultValue = "") { if (!process || !address) { return defaultValue; } SIZE_T bytesRead; char[1024] data; if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, The second cast still looks suspicious. PVOID is void*, right? Then any mutable pointer type should implicitly convert to PVOID and you shouldn't need the cast. stringSize, &bytesRead)) { return defaultValue; } auto s = cast(string)data[0 .. stringSize]; return s ? s : defaultValue; Here's an error that produces garbage. `data` is a fixed-sized array, so the values are on the stack. That means `s` points to the stack. You can't return a pointer to the stack. It becomes invalid when the function returns. You can put it on the heap instead: `auto s = data[0 .. stringSize].idup;`. }
Re: ReadProcessMemory + address from ollydbg
On Sat, Jul 01, 2017 at 02:23:36AM +0200, ag0aep6g via Digitalmars-d-learn wrote: > On 07/01/2017 01:41 AM, bauss wrote: [...] > > stringSize, &bytesRead)) { > > return defaultValue; > >} > > > >auto s = cast(string)data[0 .. stringSize]; > > > >return s ? s : defaultValue; > > Here's an error that produces garbage. > > `data` is a fixed-sized array, so the values are on the stack. That > means `s` points to the stack. You can't return a pointer to the > stack. It becomes invalid when the function returns. You can put it on > the heap instead: `auto s = data[0 .. stringSize].idup;`. [...] The compiler is supposed to catch errors like these with -dip1000. Recently there was a DIP1000-related fix checked in that fixed some of the problems with -dip1000 (specifically, a linker error I was running into), so you may want to consider compiling with -dip1000 if you're running the latest compiler. T -- Klein bottle for rent ... inquire within. -- Stephen Mulraney
Re: ReadProcessMemory + address from ollydbg
On Saturday, 1 July 2017 at 00:23:36 UTC, ag0aep6g wrote: On 07/01/2017 01:41 AM, bauss wrote: string ReadWinString(HANDLE process, DWORD address, size_t stringSize, string defaultValue = "") { if (!process || !address) { return defaultValue; } SIZE_T bytesRead; char[1024] data; if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, The second cast still looks suspicious. PVOID is void*, right? Then any mutable pointer type should implicitly convert to PVOID and you shouldn't need the cast. stringSize, &bytesRead)) { return defaultValue; } auto s = cast(string)data[0 .. stringSize]; return s ? s : defaultValue; Here's an error that produces garbage. `data` is a fixed-sized array, so the values are on the stack. That means `s` points to the stack. You can't return a pointer to the stack. It becomes invalid when the function returns. You can put it on the heap instead: `auto s = data[0 .. stringSize].idup;`. } Using ".idup" makes no difference in the result. I was under the impression the cast would already do that though, guess not. However the result is the same. I also tried to check "data" directly and it's already garbage there. Well the address is not a pointer. It's DWORD which is uint, so the cast is necessary since it stores the address.
Re: ReadProcessMemory + address from ollydbg
On 07/01/2017 02:30 AM, bauss wrote: On Saturday, 1 July 2017 at 00:23:36 UTC, ag0aep6g wrote: On 07/01/2017 01:41 AM, bauss wrote: [...] if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, The second cast still looks suspicious. PVOID is void*, right? Then any mutable pointer type should implicitly convert to PVOID and you shouldn't need the cast. [...] Well the address is not a pointer. It's DWORD which is uint, so the cast is necessary since it stores the address. Not that one. The other one. This one: `cast(PVOID)&data`. I don't expect it to be related to your problem, but it shouldn't be necessary as far as I see.
Re: ReadProcessMemory + address from ollydbg
On Saturday, 1 July 2017 at 00:40:11 UTC, ag0aep6g wrote: On 07/01/2017 02:30 AM, bauss wrote: On Saturday, 1 July 2017 at 00:23:36 UTC, ag0aep6g wrote: On 07/01/2017 01:41 AM, bauss wrote: [...] if (!ReadProcessMemory(process, cast(PCVOID)address, cast(PVOID)&data, The second cast still looks suspicious. PVOID is void*, right? Then any mutable pointer type should implicitly convert to PVOID and you shouldn't need the cast. [...] Well the address is not a pointer. It's DWORD which is uint, so the cast is necessary since it stores the address. Not that one. The other one. This one: `cast(PVOID)&data`. I don't expect it to be related to your problem, but it shouldn't be necessary as far as I see. Yeah, the cast was unnecessary. So this is my code after the changes: string ReadWinString(HANDLE process, DWORD address, size_t stringSize, string defaultValue = "") { if (!process || !address) { return defaultValue; } SIZE_T bytesRead; char[1024] data; if (!ReadProcessMemory(process, cast(LPCVOID)address, &data, stringSize, &bytesRead)) { return defaultValue; } auto s = cast(string)data[0 .. stringSize].idup; return s ? s : defaultValue; } Results are still garbage data, correct length in bytesRead however. I tried to pass the address with the main module's base address because I saw some posts online suggesting you might need to do that. If I do that however I just get error 299 (ERROR_PARTIAL_COPY), so I don't think I needed the base address, but still can't figure out what exactly is wrong with my code and why I can't read the string from the address I give it, when it's a static address. Every time I look with ollydbg the address is the same and ollydbg can find the string just fine.