Thursday, February 3, 2011

Should I move from C++ to Python? ... Or another language?

In the company I work for, we do a lot of file-based transaction processing. The processing centers around the conversion of files between numerous formats to suit numerous systems in numerous companies.

The processing almost always involves an XML stage and can include a lot of text parsing, database lookups, data conversion and data validation.

Currently the programs performing all these tasks are written in C++ and they perform quite quickly all on one average server. I'm investigating the possibilities of using a more "modern" language that newer graduate programmers are more likely to be familiar with. (Correct memory allocation in C++ seems to causes problems with a lot of newer programmers these days)

Based on the brief information provided, would a language such as python provide the required functionality and performance, as well as addressing the memory allocation (and various other C++ related) problems which arise?

I like the idea of not needing to compile the programs each time we make a change. I understand that the interpreted languages probably wont hit the same performance we currently get.

Our systems are Linux based which also restrict some options.

Any comments on the functionality and performance available with Python or suggestions of alternative languages would be much appreciated.

  • Python would probably remove most of the low level stuff that you use in your application. Memory allocation wouldn't be an issue anymore. Also, at least my university seems to be embracing Python as a programming language because students don't have to write all of that formal stuff to get started. Your only problem would be the performance part, as Python will likely never be as fast as a compiled C++ program.

    I would advise you to take a couple of weeks to get to know the programming languages that you're considering. I'd check out Ruby also. Maybe toy around with Haskell a bit?

    As I understand it Python seems well equipped for dealing with everything you're talking about. XML, database lookups, validation, parsing. It is usually a safe choice, not just because of the easy and fun programming experience, but if you're stuck there's an awesome community around the language who are just happy to help out.

    From deadtime
  • I like the idea of not needing to compile the programs each time we make a change. I understand that the interpreted languages probably wont hit the same performance we currently get.

    This is the biggest issue; can you live with the performance hit. You could try to use Python and extending it with your current C++ modules for the performance heavy parts. Still, switching your entire system seems like a big effort if the only reason is the lack of C++ talent. Hiring people who know C++ seems like the cheaper option.

    gbjbaanb : poor programmers tend to be poor with all languages, so changing everything just to suit the numpties won't be a solution. I'd recommend teaching them how to be better instead, it'll pay off significantly. (and use STL and a nice XML lib - tinyXML is good)
    From mreggen
  • Which is more important, quickly getting the programs to work, or getting the programs working quickly?

    If you're dealing with large numbers of large files then you may be better off staying in C++ and teaching your graduate programmers what a pointer is (!)

    Otherwise I'd strongly advise that you look at a scripting-based solution, because development in these, once you're up to speed, is so much faster. And a lot more fun, if we're honest, for most people at least.

    If the per-record processing load is not high, you may be surprised how little performance you lose: file IO will almost certainly be handled in a compiled (C) library, so the interpreter overhead may be relatively low. Worth trying, I'd suggest.

    Of the imperative languages, Perl is an obvious option, Python is popular and Ruby has a high profile (and probably cleaner OO features than the first two). Then there is the slightly more, er, esoteric realm of the functional languages, but I'm not qualified to comment on those.

  • Another alternative is to embed Python in your C++ program. You could keep much of your application the same, and make calls out to Python for the pieces that change often, or need the flexibility that a scripting language provides.

    From the Python docs

    The previous chapters discussed how to extend Python, that is, how to extend the functionality of Python by attaching a library of C functions to it. It is also possible to do it the other way around: enrich your C/C++ application by embedding Python in it. Embedding provides your application with the ability to implement some of the functionality of your application in Python rather than C or C++. This can be used for many purposes; one example would be to allow users to tailor the application to their needs by writing some scripts in Python. You can also use it yourself if some of the functionality can be written in Python more easily.

    From Rob Thomas
  • This is the biggest issue; can you live with the performance hit. Blockquote

    You can improve the performace using Psyco. And after all, thanks to Moor's law, performance isn't that big issue this days.

    From Samir
  • Or should try to store your parsing rules on a database instead of leaving them hard-coded inside your code. As Ken Downs rightly quoted, minimize code, maximize data. This way you would not need to recompile everytime a tiny rule changes.

  • I hate to say this, but f you want something that your incoming developers are going to be familiar with, go with Java. Java is the language that most recent graduates will be most familiar with. You still have to compile, but compile times will be shorter than C++. It'll run on Linux and pretty much anywhere else. It's got a good garbage collector. It's pretty fast. And did I mention your developers will be familiar with it? No, it's not "cool" like Python, but it's a very tried-and-true language.

    Honestly, I doubt that you've got a lot of incoming developers who suck with C++ but would be awesome with Python anyway. The people who use Python well tend to be fine with manual memory management. The people who are bad with memory management actually tend to be bad with all languages.

    I do find it worrisome that you've got developers who are so bad with memory management that you want to switch languages. That's a sign indicating a problem, but I'm not sure that the problem is with the language.

    gbjbaanb : -1 for Java (doesn't really help the OP much at all), but +1 for "people who are bad with memory management tend to be bad with all languages".
    From Derek Park
  • If you can get away with using Python, Ruby, Groovy or Perl vs. C++ you would be better off going with one of these higher level languages. Productivity will greatly increase. If you find that you need more performance then go with Java. Everyone should know at and use at least one dynamically typed language.

  • should move to python that languange make all possible in networking, if you need faster move to c/c++

Is there some way of recycling a Crystal Reports dataset?

I'm trying to write a Crystal Report which has totals grouped in a different way to the main report. The only way I've been able to do this so far is to use a subreport for the totals, but it means having to hit the data source again to retrieve the same data, which seems like nonsense. Here's a simplified example:

       date   name   earnings   source          location
-----------------------------------------------------------
12-AUG-2008   Tom      $50.00   washing cars    uptown
12-AUG-2008   Dick    $100.00   washing cars    downtown     { main report }
12-AUG-2008   Harry    $75.00   mowing lawns    around town

                    total earnings for washing cars: $150.00 { subreport }
                    total earnings for mowing lawns:  $75.00

       date   name   earnings   source          location
-----------------------------------------------------------
13-AUG-2008   John     $95.00   dog walking     downtown
13-AUG-2008   Jane    $105.00   washing cars    around town  { main report }
13-AUG-2008   Dave     $65.00   mowing lawns    around town

                    total earnings for dog walking:   $95.00
                    total earnings for washing cars: $105.00 { subreport }
                    total earnings for mowing lawns:  $65.00

In this example, the main report is grouped by 'date', but the totals are grouped additionally by 'source'. I've looked up examples of using running totals, but they don't really do what I need. Isn't there some way of storing the result set and having both the main report and the subreport reference the same data?

  • The only way I can think of doing this without a second run through the data would be by creating some formulas to do running totals per group. The problem I assume you are running into with the existing running totals is that they are intended to follow each of the groups that they are totaling. Since you seem to want the subtotals to follow after all of the 'raw' data this won't work.

    If you create your own formulas for each group that simply adds on the total from those rows matching the group you should be able to place them at the end of the report. The downside to this approach is that the resulting subtotals will not be dynamic in relationship to the groups. In other words if you had a new 'source' it would not show up in the subtotals until you added it or if you had no 'dog walking' data you would still have a subtotal for it.

    From N8g
  • Can I just ask a couple of questions so I might be able to come up with an alternate solution... are you accessing this report from within an ASP.NET application?

    If so, does the report make the call on the database directly and "pull" the data or does it have data "pushed" to if from an underlying business layer?

    From lomaxx
  • @lomaxx yep, it's accessed through a ASP.NET application and the report has a database stored procedure as its datasource. Currently, I have this stored procedure processing the data and writing the results to a table (which the subreport can use) as well as returning the result set, that way I don't have to process the data twice, just read it twice. I hope that makes sense!

    @N8g you've hit the nail on the head here:

    The problem I assume you are running into with the existing running totals is that they are intended to follow each of the groups that they are totaling. Since you seem to want the subtotals to follow after all of the 'raw' data this won't work.

    The problem with writing my own formulae is, as you pointed out, the source list is dynamic and could be different every time the report is run; hence the use of a subreport.

    From ninesided
  • Hmm... as nice as it is to call the stored proc from the report and have it all contained in one location, however we found (like you) that you eventually hit a point where you can't get crystal to do what you want even tho the data is right there.

    We ended up introducing a business layer which sits under the report and rather than "pulling" data from the report we "push" the datasets to it and bind the data to the report. The advantage is that you can manipulate the data in code in datasets or objects before it reaches the report and then simply bind the data to the report.

    This article has a nice intro on how to setup pushing data to the reports. I understand that your time/business constraints may not allow you to do this, but if it's at all possible, I'd highly recommend it as it's meant we can remove all "coding" out of our reports and into managed code which is always a good thing.

    From lomaxx

Can I configure Visual Studio NOT to change StartUp Project everytime I open a file from one of the projects?

Let's say that there is a solution that contains two projects (Project1 and Project2).

Project1 is set as a StartUp Project (its name is displayed in a bold font). I double-click some file in Project2 to open it. The file opens, but something else happens too - Project2 gets set as a StartUp Project.

I tried to find an option in configuration to change it, but I found none.

Can this feature (though it's more like a bug to me) be disabled?

  • The way to select a startup project is described in Sara Ford's blog "Visual Studio Tip of the Day" (highly recommended). She has a post there about setting up StartUp projects. Essentially there are 2 ways, the easiest one being right-clicking on the desired project, and choosing "Set As StartUp Project". That prevents other projects from becoming the StartUp project, even if you click on one their files.

    From Lea Cohen
  • Check your Visual Studio options for the following check box:
    Projects and Solutions - Build and Run - For new solutions use the currently selected project as the startup project.

    Uncheck that and see if the behavior changes.

    From kokos

Get list of domains on the network

Using the Windows API, how can I get a list of domains on my network?

  • Answered my own question:

    Use the NetServerEnum function, passing in the SVTYPEDOMAIN_ENUM constant for the "servertype" argument.

    In Delphi, the code looks like this:

    <snip>
    type
      NET_API_STATUS = DWORD;
      PSERVER_INFO_100 = ^SERVER_INFO_100;
      SERVER_INFO_100 = packed record
        sv100_platform_id : DWORD;
        sv100_name        : PWideChar;
    end;
    
    function NetServerEnum(  //get a list of pcs on the network (same as DOS cmd "net view")
      const servername    : PWideChar;
      const level         : DWORD;
      const bufptr        : Pointer;
      const prefmaxlen    : DWORD;
      const entriesread   : PDWORD;
      const totalentries  : PDWORD;
      const servertype    : DWORD;
      const domain        : PWideChar;
      const resume_handle : PDWORD
    ) : NET_API_STATUS; stdcall; external 'netapi32.dll';
    
    function NetApiBufferFree(  //memory mgmt routine
      const Buffer : Pointer
    ) : NET_API_STATUS; stdcall; external 'netapi32.dll';
    
    const
      MAX_PREFERRED_LENGTH = DWORD(-1);
      NERR_Success = 0;
      SV_TYPE_ALL  = $FFFFFFFF;
      SV_TYPE_DOMAIN_ENUM = $80000000;
    
    
    function TNetwork.ComputersInDomain: TStringList;
    var
      pBuffer        : PSERVER_INFO_100;
      pWork          : PSERVER_INFO_100;
      dwEntriesRead  : DWORD;
      dwTotalEntries : DWORD;
      i              : integer;
      dwResult       : NET_API_STATUS;
    begin
      Result := TStringList.Create;
      Result.Clear;
    
      dwResult := NetServerEnum(nil,100,@pBuffer,MAX_PREFERRED_LENGTH,
                                @dwEntriesRead,@dwTotalEntries,SV_TYPE_DOMAIN_ENUM,
                                PWideChar(FDomainName),nil);
    
      if dwResult = NERR_SUCCESS then begin
        try
          pWork := pBuffer;
          for i := 1 to dwEntriesRead do begin
            Result.Add(pWork.sv100_name);
            inc(pWork);
          end;  //for i
        finally
          NetApiBufferFree(pBuffer);
        end;  //try-finally
      end  //if no error
      else begin
        raise Exception.Create('Error while retrieving computer list from domain ' +
                               FDomainName + #13#10 +
                               SysErrorMessage(dwResult));
      end;
    end;
    <snip>
    
  • You will need to use some LDAP queries

    Here is some code I have used in a previous script (it was taken off the net somewhere, and I've left in the copyright notices)

    ' This VBScript code gets the list of the domains contained in the 
    ' forest that the user running the script is logged into
    
    ' ---------------------------------------------------------------
    ' From the book "Active Directory Cookbook" by Robbie Allen
    ' Publisher: O'Reilly and Associates
    ' ISBN: 0-596-00466-4
    ' Book web site: http://rallenhome.com/books/adcookbook/code.html
    ' ---------------------------------------------------------------
    
    set objRootDSE = GetObject("LDAP://RootDSE")
    strADsPath =  "<GC://" & objRootDSE.Get("rootDomainNamingContext") & ">;"
    strFilter  = "(objectcategory=domainDNS);"
    strAttrs   = "name;"
    strScope   = "SubTree"
    
    set objConn = CreateObject("ADODB.Connection")
    objConn.Provider = "ADsDSOObject"
    objConn.Open "Active Directory Provider"
    set objRS = objConn.Execute(strADsPath & strFilter & strAttrs & strScope)
    objRS.MoveFirst
    while Not objRS.EOF
        Wscript.Echo objRS.Fields(0).Value
        objRS.MoveNext
    wend
    


    Also a C# version

Delphi MDI Application and the titlebar of the MDI Children

I've got an MDI application written in Delphi 2006 which runs XP with the default theme. Is there a way of controlling the appearance of the MDI Children to avoid the large XP-style title bar on each window? I've tried setting the BorderStyle of the MDIChildren to bsSizeToolWin but they are still rendered as normal Forms.

  • I don't think there is; in my experience, MDI in Delphi is very strictly limited and controlled by its implementation in the VCL (and perhaps also by the Windows API?). For example, don't try hiding an MDI child (you'll get an exception if you try, and you'll have to jump through a couple of API hoops to work around that), or changing the way an MDI child's main menu is merged with the host form's.

    Given these limitations, perhaps you should reconsider why you'd like to have special title bars in the first place? I guess there are also good reasons why this MDI stuff is standardized --- your users might appreciate it :)

    (PS: nice to see a Delphi question around here!)

    From onnodb
  • Thanks onnodb

    Unfortunately the client insists on MDI and the smaller title bar.

    I have worked out one way of doing it which is to hide the title bar by overriding the windows CreateParams and then create my own title bar (simple panel with some Mouse handling for moving). Works well enough so I think I might run it by the client and see if it will do...

    From Marius
  • The way MDI works doesn't gel with what you're trying to do.

    If you need the "MDI" format, you should consider using either the built-in or a commercial docking package, and use the docking setup to mimic the MDI feel.

    In my Delphi apps, I frequently use TFrames and parent them to the main form, and maximizing them so they take up the client area. This gives you something similar to how Outlook looks. It goes a little something like this:

    TMyForm = class(TForm)
    private
      FCurrentModule : TFrame;
    public
      property CurrentModule : TFrame read FModule write SetCurrentModule;
    end;
    
    procedure TMyForm.SetCurrentModule(ACurrentModule : TFrame);
    begin
      if assigned(FCurrentModule) then
        FreeAndNil(FCurrentModule);  // You could cache this if you wanted
      FCurrentModule := ACurrentModule;
      if assigned(FCurrentModule) then
      begin
        FCurrentModule.Parent := Self;
        FCurrentModule.Align := alClient;
      end;
    end;
    

    To use it, you can simply do this:

    MyForm.CurrentModule := TSomeFrame.Create(nil);
    

    There is a good argument that you should use interfaces (creating an IModule interface or something) that you use. I often do that, but it's more complex than needed to explain the concept here.

    HTH

  • All your need - overload procedure CreateWindowHandle, like this:

    unit CHILDWIN;
    interface
    uses Windows, Classes, Graphics, Forms, Controls, StdCtrls;
    
    type
      TMDIChild = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
        procedure CreateWindowHandle(const Params: TCreateParams); override;
      end;
    
    implementation
    
    {$R *.dfm}
    procedure TMDIChild.CreateWindowHandle(const Params: TCreateParams);
    begin
      inherited CreateWindowHandle(Params);
      SetWindowLong(Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
    end;
    end.
    
    From CoolMagic
  • Thank you very much from CoolMagic

    From asgarkz

Getting accurate ticks from a timer in C#

I'm trying to rebuild an old metronome application that was originally written using MFC in C++ to be written in .NET using C#. One of the issues I'm running into is getting the timer to "tick" accurately enough.

For example, assuming an easy BPM (beats per minute) of 120, the timer should tick every .5 seconds (or 500 milliseconds). Using this as the basis for the ticks, however, isn't entirely accurate as .NET only guarantees that your timer will not tick before the elapsed time has passed.

Currently, to get around this for the same 120 BPM example used above, I am setting the ticks to something like 100 milliseconds and only playing the click sound on every 5th timer tick. This does improve the accuracy quite a bit, but if feels like a bit of a hack.

So, what is the best way to get accurate ticks? I know there are more timers available than the windows forms timer that is readily available in Visual Studio, but I'm not really familiar with them.

  • There are three timer classes called 'Timer' in .NET. It sounds like you're using the Windows Forms one, but actually you might find the System.Threading.Timer class more useful - but be careful because it calls back on a pool thread, so you can't directly interact with your form from the callback.

    Another approach might be to p/invoke to the Win32 multimedia timers - timeGetTime, timeSetPeriod, etc.

    A quick google found this, which might be useful http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx

    'Multimedia' (timer) is the buzz-word to search for in this context.

    From Will Dean
  • What is the C++ application using? You can always use the same thing or wrap the timer code from C++ into a C++/CLI class.

    From Coincoin
  • Timer classes can start behaving strangely when the timer 'tick' event code is not finished executing by the time the next 'tick' occurs. One way to combat this is to disable the timer at the beginning of the tick event, then re-enable it at the end.

    However, this approach is not suitable in cases where the execution time of the 'tick' code is not acceptable error in the timing of the tick, since the timer will be disabled (not counting) during that time.

    If disabling the timer is an option, then you can also achieve the same effect by creating a separate thread that executes, sleeps for x milliseconds, executes, sleeps, etc...

    Wilhelm : But then you can only be sure that the thread sleeps at least x millioseconds; the thread scheduler does not certify that the thread will run at the exact millesond count
    Brad Barker : Right. I agree with what you said about not being able to pinpoint the time of the next tick. The point of what I am saying is you don't want to be executing tick event code from a previous tick when your next tick occurs.
  • System.Windows.Forms.Timer is limited to an accuracy of 55 milliseconds...

    From yazanpro

Is there any list datatype in MySQL stored procedures, or a way to emulate them?

I would like to create a stored procedure in MySQL that took a list as argument. For example, say that I would like to be able to set multiple tags for an item in one call, then what I want to do is to define a procedure that takes the ID of the item and a list of tags to set. However, I can't seem to find any way to do this, there is no list datatype, as far as I'm aware, but can it be emulated somehow? Could the list of tags be a comma-separated string, which can somehow be split and looped over?

How do you usually work with lists in MySQL stored procedures?

  • Hmmm, not sure if these will work specifically in a SP, but there are ENUM and SET datatypes in MySQL 5 which may do what you need. http://dev.mysql.com/doc/refman/5.0/en/enum.html http://dev.mysql.com/doc/refman/5.0/en/set.html

  • In my programming language of Choice, C#, I actually do this in the application itself because split() functions and loops are easier to program in C# then SQL, However!

    Perhaps you should look at SubString_Index() function.

    For example, the following would return google:

    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('www.google.com', '.', -2), '.', 1);
    
    From GateKiller
  • Depending on how complicated you want to get, you can use a generic linking table. For one of my applications there are several reports where the user might pick, for instance a list of customers to run the report on rather than just a single customer from a combo box. I have a separate table with 2 fields:

    • UniqueID (guid)
    • ItemID

    The psuedo-code looks like this:

    GUID guid = GenerateGUID()
    try
      for each customer in customerList { INSERT(guid, customerId) }
      ExecuteSQLPocedure(guid)
      --the procedure can inner-join to the list table to get the list
    finally
      DELETE WHERE UniqueID=guid
    
    From Clyde
  • This article has some good discussion on the problem of parsing an array to a stored procedure since stored procedures only allow valid table column data-types as parameters.

    There are some neat things you can do with the csv table type in mysql - that is if you are loading a flat file into the db.

    You could create a temporary table in the stored procedure, iterate over the csv list and insert it to the temp table, then create a cursor which selects the values from that table. This answer in the above mentioned thread shows a way of doing this.

    Generally I would split the array before I come to the database and then perform the query individually on each item.

    From roo

Not showing Dialog when opening file in Acrobat Pro using Applescript

When opening Adobe Acrobat Pro, whether it be through Applescript or finder, the introductory dialog is shown. Is there a way to not show this dialog without already having checked the "Don't Show Again" option when opening a document using Applescript?

Photoshop and Illustrator Applescript libraries have ways of setting interaction levels and not showing dialogs, but I can't seem to find the option in Acrobat.

  • Copy any applicable preferences files in ~/Library/Preferences from a machine that you have checked "Don't show again" on.

    From Adam Ernst
  • If it's not in the dictionary, probably not.

    From Mike Heinz

[C#] Best implementation for Key Value Pair Data Structure?

So I've been poking around with C# a bit lately, and all the Generic Collections have me a little confused. Say I wanted to represent a data structure where the head of a tree was a key value pair, and then there is one optional list of key value pairs below that (but no more levels than these). Would this be suitable?

public class TokenTree
{
    public TokenTree()
    {
        /* I must admit to not fully understanding this,
         * I got it from msdn. As far as I can tell, IDictionary is an
         * interface, and Dictionary is the default implementation of
         * that interface, right?
         */
        SubPairs = new Dictionary<string, string>();
    }

    public string Key;
    public string Value;
    public IDictionary<string, string> SubPairs;
}

It's only really a simple shunt for passing around data.

  • There is an actual Data Type called KeyValuePair, use like this

    KeyValuePair<string, string> = new KeyValuePair<string,string>("defaultkey", "defaultvalue");
    
    From Adam Haile
  • Dictionary Class is exactly what you want, correct.

    You can declare the field directly as Dictionary, instead of IDictionary, but that's up to you.

  • There is a KeyValuePair built-in type. As a matter of fact, this is what the IDictionary is giving you access to when you iterate in it.

    Also, this structure is hardly a tree, finding a more representative name might be a good exercise.

    From Coincoin
  • One possible thing you could do is use the Dictionary object straight out of the box and then just extend it with your own modifications:

    public class TokenTree : Dictionary<string, string>
    {
        public IDictionary<string, string> SubPairs;
    }
    

    This gives you the advantage of not having to enforce the rules of IDictionary for your Key (e.g., key uniqueness, etc).

    And yup you got the concept of the constructor right :)

    From Jon Limjap
  • @Jay Mooney: A generic Dictionary class in .NET is actually a hash table, just with fixed types.

    The code you've shown shouldn't convince anyone to use Hashtable instead of Dictionary, since both code pieces can be used for both types.

    For hashtable:

    foreach(object key in h.keys)
    {
         string keyAsString = key.ToString(); // btw, this is unnecessary
         string valAsString = h[key].ToString();
    
         System.Diagnostics.Debug.WriteLine(keyAsString + " " + valAsString);
    }
    

    For dictionary:

    foreach(string key in d.keys)
    {
         string valAsString = d[key].ToString();
    
         System.Diagnostics.Debug.WriteLine(key + " " + valAsString);
    }
    

    And just the same for the other one with KeyValuePair, just use the non-generic version for Hashtable, and the generic version for Dictionary.

    So it's just as easy both ways, but Hashtable uses Object for both key and value, which means you will box all value types, and you don't have type safety, and Dictionary uses generic types and is thus better.

  • Wow, C# questions get answered a lot faster than C++ ones (:D). I think a KeyValuePair and a Dictionary<string, string> will work nicely.

    @Coincoin:
    Yeah, naming stuff has never been my strong point.
    What would you recommend? ListOfKVPsThatHasSubKVPs is more of a Java name... ;p

    From Bernard
  • Use something like this:

    class Tree < T > : Dictionary < T, IList< Tree < T > > >  
    {  
    }
    

    It's ugly, but I think it will give you what you want. Too bad KeyValuePair is sealed.

    From kokos
  • Just one thing to add to this (although I do think you have already had your question answered by others). In the interests of extensibility (since we all know it will happen at some point) you may want to check out the Composite Pattern This is ideal for working with "Tree-Like Structures"..

    Like I said, I know you are only expecting one sub-level, but this could really be useful for you if you later need to extend ^_^

    From Rob Cooper
  • I think what you might be after (as a literal implementation of you question) is:

    pubic class TokenTree
    {
        public TokenTree()
        {
            tree = new Dictionary<string, IDictionary<string,string>>();
        }
    
        IDictionary<string, IDictionary<string, string>> tree; 
    }
    

    You did actually say a "list" of key-values in your question so you might want to swap the inner IDictionary with a:

    IList<KeyValuePair<string, string>>
    
  • @rob:
    Looks interesting, I'll give it a read.

    @techdissonance:
    Doesn't that give me a key associated with a key value pair? Or am I missing something?

    From Bernard

Ant build scripts, antcall, dependencies, etc

I have a build script and as part of that script it copies a jar file to a directory, for ease lets call it the utils jar. the utils jar is built by another build script sitting in another directory. What im trying to do have my build script run the utils build script so that I can ensure the utils jar is up to date.

So I know I need to import the utils build file.

<import file="../utils/build/build.xml" />

Which doesn't work because the import task, unlike almost every other ant taks, doesn't run from basedir, it runs from the pwd. So to get around that I have this little ditty, which does successfully import the build file

  <property name="baseDirUpOne" location=".." />
  <import file="${baseDirUpOne}/utils/build/build.xml" />

So now that ive solved my import problem I need to call the task, well that should be easy right:

<antcall target="utils.package" />

note that in the above, utils is the project name of ../utils/build/build.xml

the problem I'm now running into is that ant call doesn't execute in ../utils/build so what I need, and cant find, is a runat property or something similar, essentially:

<antcall target="utils.package" runat="../utils/build" />

The reason I need this is that in my utils build file the step to select which code to copy to the jar is based on relative paths so as to avoid hardcoding paths in my ant file. Any ideas?

  • I've got something similar set up: I have a main Ant build.xml which calls a separate build.xml that takes care of building my tests. This is how I do it:

    <target name="build-tests">
        <subant target="build">
          <fileset dir="${test.home}" includes="build.xml"/>
        </subant>
    </target>
    

    The trick is to use subant instead of antcall. You don't have to import the other build file.

    Stephane Grenier : What if you need to adjust the classpath in the subant target?
    From Theo
  • Try using the "ant" task instead of the "antcall" task, which runs the imported build directly instead of importing it into the current build file. It has a "dir" parameter:

    the directory to use as a basedir for the new Ant project. Defaults to the current project's basedir, unless inheritall has been set to false, in which case it doesn't have a default value. This will override the basedir setting of the called project.

    So you could do:

    <antcall antfile="${baseDirUpOne}/utils/build/build.xml" dir="../utils/build" />
    

    or something like that.

    Ben Clark-Robinson : Make that
  • You can pass params down to antcall using nested in the antcall block. So, you can pass the properties down that way (probably even basedir since properties are immutable).

    From Peter Kahn

Cannot add WebViewer of ActiveReports to an ASP.NET page

I installed ActiveReports from their site. The version was labeled as ".NET 2.0 build 5.2.1013.2 (for Visual Studio 2005 and 2008)". I have an ASP.NET project in VS 2008 which has 2.0 as target framework. I added all the tools in the DataDynamics namespace to the toolbox, created a new project, added a new report.

When I drag and drop the WebViewer control to a page in the design view, nothing happens. No mark up is added, no report viewer is displayed on the page. Also I noticed that there are no tags related to DataDynamics components in my web.config file. Am I missing some configuration?

  • I think I found the reason. While trying to get this work, I think I installed another version of the package that removed or deactivated my current version. The control I was dropping on the form belonged to the older version that had no assemblies referenced. I removed all installations of ActiveReports, installed the last version and cleaned up the toolbox. I added the latest version of the WebViewer to toolbox and dropped it on the form. It worked.

Import Namespace System.Query

I am trying to load Linq on my .Net 3.5 enabled web server by adding the following to my .aspx page:

<%@ Import Namespace="System.Query" %>

However, this fails and tells me it cannot find the namespace.

The type or namespace name 'Query' does not exist in the namespace 'System'

I have also tried with no luck:

  • System.Data.Linq
  • System.Linq
  • System.Xml.Linq

I believe that .Net 3.5 is working because var hello = "Hello World" seems to work.

Can anyone help please?

Cheers, Stephen

PS: I just want to clarify that I don't use Visual Studio, I simple have a Text Editor and write my code directly into .aspx files.

  • The var hello stuff is compiler magic and will work without Linq.

    Try adding a reference to System.Core


    Sorry, I wasn't clear. I meant add System.Core to the web project's references, not to the page.

    The Import on the page are basically just using statements, allowing you to skip the namespace on the page.

    From Keith
  • Hi Keith, adding:

    <%@ Import Namespace="System.Core" %>
    

    failed to work and showed the same error message :(

    Any other idea's?

    From GateKiller
  • Make sure your project is set to target 3.5, and not 2.0.

    As others have said, your 'var' test is a test of C#3 (i.e. VS2008), not the 3.5 framework.

    If you set the project framework target settings properly, you should not expect to need to manually add dll references at this point.

    From Will Dean
  • Hi Will,

    I'm not using VS. Is there any other way I can confirm if 3.5 is installed correctly?

    From GateKiller
  • Updated original question.

    From GateKiller
  • What version of the framework have you selected on the ASP.NET tab in IIS?

    From Will Dean
  • <%@ Import Namespace="System.Core" %>

    failed to work and showed the same error message :(

    Keith was talking about adding a DLL reference, rather than another import. To be honest, I would suggest you start with Visual Studio (one of the free versions), as it will finesse this sort of stuff for you until you're a bit more up-to-speed with .NET development.

    From Will Dean
  • What version of the framework have you selected on the ASP.NET tab in IIS?

    I have version 2 selected in IIS and I have the following in my web.config:

    <system.codedom>
     <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
       type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
       <providerOption name="CompilerVersion" value="v3.5"/>
       <providerOption name="WarnAsError" value="false"/>
      </compiler>
     </compilers>
    </system.codedom>
    

    Help :(

    From GateKiller
  • I have version 2 selected in IIS and I

    Well, surely that's your problem? Select 3.5.

    Actually, here's the real info:

    http://www.hanselman.com/blog/HowToSetAnIISApplicationOrAppPoolToUseASPNET35RatherThan20.aspx

    From Will Dean
  • @Will, Yup, I have gone through those step. Like I said, I believe 3.5 is working because the syntax

    var string = "hello";
    

    works because this is a new feature of .Net 3.5.

    I'm completely at a loss now.

    PS: Thanks for your help though :)

    From GateKiller
  • var string = "hello";

    works because this is a new feature of .Net 3.5.

    As at least two people have already tried to tell you in here, this is NOT A FEATURE OF .NET 3.5

    It's a feature of C#3, which is the version of the language supported by the compiler that comes with VS2008.

    I find it hard to believe you've read and comprehended that Hanselman article, which seems to cover exactly what you're trying to do.

    From Will Dean
  • What does the part of your web.config file look like?

    Here's what it looks like for a brand new ASP.NET 3.5 project made with Visual Studio 2008:

    <assemblies>
      <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
      <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
      <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    </assemblies>
    
  • I found the answer :) I needed to add the following to my web.config:

    <assemblies>  
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>  
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>  
        <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>  
        <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>  
        <add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    </assemblies>
    

    Then I could add the following to my code:

    <%@ Import Namespace="System.Linq" %>
    

    @Will,

    Thanks for your help. I have accepted one of your answers :)

    From GateKiller
  • The csproj file might be missing the System.Core reference. Look for a line in the csproj file like this:

    <Reference Include="System" />
    

    And add a line below it like this:

    <Reference Include="System.Core" />
    
    From aboy021

Code crash in MS Visual Studio 2005 in RELEASE configuration

Hi,

I have a workspace for running an H.263 Video Encoder in a loop for 31 times i.e. the main is executed 31 times to generate 31 different encoded bit streams. This MS Visual Studio 2005 Workspace has all C source files. When i create a "DEBUG" configuration for the workspace and build and execute it, it runs fine, i.e. it generates all the 31 output files as expected. But when I set the configuration of the workspace to "RELEASE" mdoe, and repeat the process, the encoder crashes at some test case run.

Now to debug this is verified following:

  1. Analyzed the code to see if there was any variable initialization being missed out in every run of the encoder
  2. Checked the various Workspace(Solution) options in both the modes (DEBUG and RELEASE).

There are some obvious differences, but i turned the optimization related options explicitly same in both modes.

But still could not nail the problem and find a fix for that. Any pointers?

-Ajit.

  • Are you sure there are no precompile directives that, say, ignores some really important code in Release mode but allows them in Debug?

    Also, have you implemented any logging that might point out to the precise assembly that's throwing the error?

    From Jon Limjap
  • It's hard to say what the problem might be without carefully inspecting the code. However...

    One of the differences between debug and release builds is how the function call stack frame is set up. There are certain classes of bad things you can do (like calling a function with the wrong number of arguments) that are not fatal in a debug build but crash horribly in a release build. Perhaps you could try changing the stack frame related options (I forget what they're called, sorry) in the release build to the same as the debug build and see whether that helps.

    Another thing might be to enable all the warnings you possibly can, and fix them all.

  • Could be a concurrency problem of two threads. The DEBUG configuration slows the execution down, so the problem does not occur. But, only a guess.

  • Interesting problem.. Are you sure you have no conditional compilation code lurking around that is not being compiled in release mode? i.e:

    #if (DEBUG)
    // Debug Code here
    #else
    // Release Code here
    #endif
    

    Thats the only thing I can really think of.. Never experienced anything like this myself..

    From Rob Cooper
  • I would look at the crash in more detail - if it's crashing in a test case, then it sounds pretty easily reproducible, which is usually most of the challenge.

    From Will Dean
  • Can you add the debug symbols to the release build and run it in the debugger to see where and why it crashed?

  • Also to consider: in debug mode, the variables are initialized with 0xCCCCCCCC instead of zero. That might have some nasty side effects.

  • Yeah, those bastard crashes are the hardest to fix. Fortunatly, there are some steps you can do that will give you clues before you resort to manually looking at the code and hope to find the needle.

    When does it crash? At every test? At a specific test? What does that test does that the others don't?

    What's the error? If it's an access violation, is there a pattern to where it happens? If the addresses are low, it might mean there is an uninitialised pointer somewhere.

    Is the program crashing with Debug configuration but without the debugger attached? If so, it's most likely a thread synchronisation problem as John Smithers pointed out.

    Have you tried running the code through an analyser such as Purify? It's slow but it's usually worth the wait.

    Try to debug the release configuration anyway. It will only dump assemblies but it can still give you an indication of what happens such as if the code pointer jumps in the middle of garbage or hits a breakpoint in an external library.

    Are you on an Intel architecture? If not, watch for memory alignement errors, they hard crash without warning on some architectures and those codec algorithm tend to create those situations a lot since they are overly optimized.

    From Coincoin

MSVC6: Breakpoint stops program - WTF?

Using Microsoft Visual Studio 98, Microsoft Visual C++ 6.0 SP6

When running under the debugger, there's only one problem. If I pause the program and resume, everything's fine.

The problem? When I hit a breakpoint, my program stops. But not in a good way; execution halts, I'm thrown out of debug mode into edit mode. All's fine until a breakpoint is hit. And I know it's hitting the breakpoint - I see a flash of the little yellow arrow pointing at the right line of code, local variables in the inspect window and the call stack in that window. And then I'm staring at the editor.

This happens in all projects.

I've uninstalled and re-installed MSVC6. It didn't help.

I'm about to start over on a new PC; before I go that far, anyone know what I've done to this one?


Note: MSVC6 is not my choice, but there are reasons. It's the tool I work with. And, we get to target NT4, so given 2008 can't target NT4 and 2005 has issues with MFC and NT4, MSVC6 it is.

  • I haven't used MSVC6 in years, but I remember the debugger basically being a flaky piece of crap. Things like this would regularly happen for no apparent reason because it just didn't like your code that day.

    In addition to the debugger being a flaky piece of crap, the rest of it was too.

    It's STL implementation isn't threadsafe, it doesn't support very much of the C++ standard, and the IDE is sorely lacking in niceties.

    I'm pretty sure you also just simply can't use any versions of the Platform SDK from the last 5 years because it's too old to grok them. Not a good thing.

    You'd be mad to keep using it when there is Visual C++ Express 2008 which you can download for free.

  • Stop beating on VC6. It's old. The STL was updated in 1996 from HP code written in 1994. C++ was ratified in 1998.

    What is the code doing when you are breaking? Can you reduce the situation into a simple test. When I try that I usually find the cause. If you can do that so it still happens then I'll take a look at it for you. I too am unfortunate enough to use VC6 for my day to day work.

    Visual C++ Express 2008 can't be used in certain situations.

  • Is it specific to the app you're working on or do all breakpoints in any app break the debugger?

    Is anything different if you attach the debugger manually after launching the app normally?

    From Aidan Ryan
  • The first thing I would check is if this project does the same thing on other machines. If not, it could be your box is heading south. If not it's the VC6 project itself.

    Typically I get goofiness with the debugger when my program is doing something with the hardware, especially the video.

    I would recommend turning off parts of your program until you figure out what part is causing this. If your program is small and not doing much it might be that the project is corrupted and needs to get rebuilt. Make a new project from scratch and put your files and settings back in by hand.

    From Jon Clegg
  • Is the device running out of memory and therefore gives up the ghost when it requires the additional memory to stop at the breakpoint?

  • Is the device running out of memory and therefore gives up the ghost when it requires the additional memory to stop at the breakpoint?

    No, there's over a gig of RAM to go, and even more of virtual memory.

    From Josh