Deprecated: The behavior of unparenthesized expressions containing both '.' and '+'/'-' will change in PHP 8: '+'/'-' will take a higher precedence in /home/iano/public_html/tpforums-vb5/forum/includes/class_core.php on line 5842

PHP Warning: Use of undefined constant MYSQL_NUM - assumed 'MYSQL_NUM' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: Use of undefined constant MYSQL_ASSOC - assumed 'MYSQL_ASSOC' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: Use of undefined constant MYSQL_BOTH - assumed 'MYSQL_BOTH' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in ..../includes/functions_navigation.php on line 588

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in ..../includes/functions_navigation.php on line 612

PHP Warning: Use of undefined constant misc - assumed 'misc' (this will throw an Error in a future version of PHP) in ..../global.php(29) : eval()'d code(6) : eval()'d code on line 1

PHP Warning: Use of undefined constant index - assumed 'index' (this will throw an Error in a future version of PHP) in ..../global.php(29) : eval()'d code(6) : eval()'d code on line 1

PHP Warning: Use of undefined constant misc - assumed 'misc' (this will throw an Error in a future version of PHP) in ..../includes/class_bootstrap.php(1422) : eval()'d code(4) : eval()'d code on line 1

PHP Warning: Use of undefined constant index - assumed 'index' (this will throw an Error in a future version of PHP) in ..../includes/class_bootstrap.php(1422) : eval()'d code(4) : eval()'d code on line 1

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6
New container structure traversing in C# - Page 3
Page 3 of 4 FirstFirst 1234 LastLast
Results 21 to 30 of 34

Thread: New container structure traversing in C#

  1. #21
    Senior Member
    Join Date
    Jan 2012
    Posts
    417
    Quote Originally Posted by pater View Post
    @Blequi

    What is an advantage of using Marshal.AllocHGlobal and Marshal.PtrToStructure methods for allocating unmanaged memory to read data over the method which uses managed byte array like it is done in tibiaapi ? Is it performance issue ?
    It depends sincerely how you read memory.

    You can use byte arrays to read a single 32-bit integer and read each offset separated and it will cause a huge overhead, because each p/invoke in .NET uses from 10 to 30 machines instructions (http://msdn.microsoft.com/en-us/library/ms235282.aspx in the "Performance Considerations") per call, then the less ReadProcessMemory call, the better.

    On the other hand, you can still cache the structure to a byte array and convert yourself the offsets involved (commonly calling methods from BitConverter class). Since byte[] is considered by microsoft itself a blittable type, you haven't the overhead attached to Marshal the buffer. This way works really good related to performance.

    Since IntPtr is a blittable type, it is, at least, as fast as the byte[] buffer approach, but I didn't need to make several conversions using BitConverter methods, and in thesis, I don't need to allocate an array (of bytes) in managed memory. Another point, it only uses a single DllImport and following Sketchy's idea, I provided a general way to read ANY struct, without the need to create a "Read_X_Struct", I posted the method "T Read<T>(int address)" and the "T[] ReadArray<T>(int address, int count)" which is really useful to map the memory like you do in unmanaged languagues like C++.

    Remember that it was my personal tests, although it's a fast and reliable way to read structures from memory. You can use the same strategy to read battle list, tiles, everything in memory.

    The only point which I'm really in caution is the fact it is using structs. You must take care when using structs when passing it to a function call, preferable to pass it by ref, avoiding the copy being made. For example, if you are dealing with a heavy structure like Creature (0xC0 bytes long) or Tile (0x148 bytes long), if you pass it to some method or even assign it to another field, you will cause the .NET copy all the data contained and pass the copy. If you do it several times, for sure you'll notice the performance hit.

    EDIT: You gave me a good experiment to make based on my last paragraph. I'll do some tests using classes with a sequential layout to heavy data like Creature or Tile and using a DllImport passing an object as buffer, marshaling it as any.

    EDIT2: Just noticed the functions "T Read<T>(int address)" and the "T[] ReadArray<T>(int address, int count)" still works for classes with StructLayout sequential. This might be the best choice for heavy data
    Last edited by Blequi; 07-25-2013 at 04:56 PM. Reason: Edit 2

  2. #22
    Senior Member
    Join Date
    Sep 2007
    Posts
    230
    Quote Originally Posted by Blequi View Post
    mate, your snippet gave me a good idea to read structs in .NET (I guess it is probably what you are doing in the background and is a really plausible way to automate code and build the layout of several structures)... I was doing like a dumb copying/pasting my code and your code gave me the right direction once again. Maybe I'm going to rewrite a huge part of my bot, anyway I'm really excited for these new discoveries
    I've done it like you are with an unmanaged memory buffer and Marshal.PtrToStructure before, but the program that particular snippet came from I was testing a different method using runtime generated methods using IL which passes the structure directly to RPM. Never got around to doing performance comparison with an unmanaged buffer + PtrtoStruct but I suspect my IL method would be slower when reading arrays since it makes a RPM call for each element since I could never get the marshaler to marshal the entire array at once. Another idea I briefly toyed with is to create a new type at runtime with different P/Invoke definitions for different structures, I wasn't fond of the setup I had at the time though so never really followed through with it but it should work good if you create the type and all definitions at startup and should work for reading into an array (depending on what's in the structure though). Yet another idea is to create a delegate to RPM with Marshal.GetDelegateForFunctionPointer, never actually tried this since I already know it has a higher overhead than the way my IL method calls RPM.

    It's been a while since I messed around with it though and never got to a point where I was completely happy with my implementation, I'll have to look back into it some time and figure out which method is actually the fastest but they are all probably perform fine for most purposes.

    Anyway glad my snippet gave you the idea, I was actually hoping someone would pick up on it and inspire them to try something different

  3. #23
    Thanks Blequi for explantation. I know that disadvantage of structure is passing it by val not ref but creating value type is faster than creating ref type due to heap allocation. Moreover i am pretty sure that it is desirable to use sequencial StructLayout as well in structures not only in classes.

  4. #24
    Senior Member
    Join Date
    Jan 2012
    Posts
    417
    Quote Originally Posted by pater View Post
    Moreover i am pretty sure that it is desirable to use sequencial StructLayout as well in structures not only in classes.
    yeah, I didn't put it explicitly in my code, because sequential layout for structs is the default .NET behavior, but for classes, you must require it explicitly.

  5. #25
    Senior Member
    Join Date
    Sep 2007
    Posts
    230
    I always explicitly add the sequential attribute to my structures even though I know it's the default behaviour, if nothing else it lets me know a structure is used with native code without having to use some special naming convention on either the structure or its namespace.

    In somewhat related news several hours ago I started work on my own marshaller out of interest, and boredom (it was mostly boredom ), in how well it would work. So far I've created my own implementation of SizeOf which is mostly complete, and thanks to caching the type information in the first call it actually slightly outperforms Marshal.SizeOf in my tests. I also have a mostly working implementation of StructureToPtr which will correctly marshal primitive value type fields, ByValArray value type arrays, ByValTStr strings and it should support (though not tested yet) structures too. Unfortunately the current StructureToPtr implementation is very slow, almost 8 times slower than the Marshal class version, which I'm sure is due to how I'm reading the field values and copying them to the native memory (took damn ages to figure out how I could do it). I've got a few ideas on how I could speed things up though, but even if I don't match the speed (which likely will be the case) it should still be quick enough for use and should allow better customisation of the marshalling behaviour than the default marshaller does. Should be an interesting project to keep me occupied for some time.

  6. #26
    Senior Member
    Join Date
    Jan 2012
    Posts
    417
    Quote Originally Posted by Sketchy View Post
    Looking at your code there's two improvements you can make to your search. The first is to start with the centre (parent) node of the first node which points to the top-most node in the tree, the first node is actually a special node that all others point back to when they don't have a left/parent (only for top node)/right node. Secondly remove the centre search from your recursive function, since you are now starting with the top node there's nothing to search for above. You can also get all nodes sorted in ascending key order by calling the left recursion before the right and adding the node to your storage object between them. This is how I'm actually reading it in my generic STLMap class in a few of my things - http://pastebin.com/QN9FLcU4
    following these tips, VC++ 2010 console application (disregard memory flaws and bad c++ code design in general, if you found):

    http://pastebin.com/eTemUNuH

  7. #27
    Senior Member
    Join Date
    Jan 2008
    Location
    Cambridge, England
    Posts
    725
    Quote Originally Posted by Blequi View Post
    following these tips, VC++ 2010 console application (disregard memory flaws and bad c++ code design in general, if you found):

    http://pastebin.com/eTemUNuH
    Nice code there mate, makes me wanna work in C++ again lol

  8. #28

  9. #29
    Member
    Join Date
    Feb 2009
    Posts
    76
    I think everyone can use C#_to_VB.NET converter...

  10. #30
    Junior Member
    Join Date
    Aug 2012
    Posts
    21
    Quote Originally Posted by panqnik View Post
    I think everyone can use C#_to_VB.NET converter...
    Yes, but is have some error in code

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •