DLL in TestStand

Hi,
       I am having a DLL that is returning a pointer to character. Is there any provision to receive that pointer in TestStand. I am using this DLL as an adapter in TestStand. While the DLL is getting attached, TestStand is not recognizing the prototype of the DLL and also TestStand is not returning other than numeric and boolean.
        Looking for help !!!
Thanks in advance,
Vivek

You cannot return a string as the return value
of a function to TestStand, but you can return a string as a char
buffer parameter.
Declare your function as follows:
void __declspec(dllexport) Read(char data[])
    strcpy(data, "Hello");

Similar Messages

  • Problems in using Labview DLL with TestStand!

    Hi,
    I tried to put the VI's to create a TCP/IP Connection, read/write Data to it and close it inside a LabVIEW DLL and use these functions with TestStand.
    The problem is to get access to the ConnectionID generated as TCP Network Refnum in LabVIEW.
    I don't know how to specify the prototype entry for this Refnum in LabVIEW and how to read it with TestStand.
    Another try to pass an ActiveXReference of SequenceContext and use the SetValIDispatch method to set a local variable (Type: ActiveXReference) to the returned ConnectionID of the TCPOpen.VI wasn't successful too.
    It seems to me that the connectionID isn't a normal ActiveXReference.
    Regards,
    Sunny

    Hi Sunny -
    You should treat this parameter as a pointer to an int when calling the DLL from TestStand (or any language like C or C++). Note that you can't do anything with the value outside of LabVIEW since it only has meaning inside of LabVIEW. You can only pass it around for use in other VIs you call from TestStand.
    Hope this helps....
    Kyle G.
    National Instruments
    Kyle Gupton
    LabVIEW R&D
    National Instruments

  • Pass cluster through DLL to Teststand

    I have to pass  Time Stamp & number thr'  a cluster in a DLL to Teststand
    thts  generating error  System Level Exception.[Error Code: -17502] 
    the Cluster ProdOrder(in pic ) is generating Issues
    Attachments:
    clustertoDLLpass Error.PNG ‏149 KB

    the Custom datatype tht I have to generate for this Cluster in teststand  cld be also   the culprit
    I have added the Mytypes ini file  where I have defined     the datatype as ProdorderMYINI
    Attachments:
    MyTypes.ini ‏3 KB
    testDLL_CLUSTER.seq ‏5 KB
    clusterPO1.vi ‏9 KB

  • How can I pass a Variant to a C++ DLL from TestStand?

    I have a VARIANT that is being returned to TestStand via COM. The variant contains a structure of integers and strings. The integers are not uniformly sized... some are 8,16, and 32 bit. Rather than try to find a way to decode this information in TestStand, I would like to pass it to a C++ DLL to do the decoding and return the information in a readily usable format. I also have need to take the aforementioned data types, send them to a DLL for conversion into a VARIANT, and then pass this variant to a COM object. Can someone please explain a way that I can use TestStand as a pass-through for VARIANTs between a COM object and a C++ DLL?

    Hi,
    To pass a VARIANT to a C++ DLL in TestStand, you will need to create a custom data type.  From the sequence, change the View ring to Sequence File Types.  Right-click to insert a new Customer Data Type and select Container.  Now you can right-click to insert a field, which you can specify what data type it is.  Insert as many fields as needed.  After you have entered those in, right-click on the Custom Data Type name and select Properties.  Go to the C Struct Passing tab and click the "Allow Objects of this Type to be Passed as Structs".  Change packing to correlate with the C++ compiler you are using and also configure the properties for each field.
    Once you have done this, you will be able to pass that VARIANT as a struct to a C++ DLL.
    Thanks,
    Terry S.
    Staff Software Engineer
    National Instruments

  • Using cvirte.dll from teststand

    I am trying to use cvirte.dll from teststand to automatically print test result reports. I am starting with the example sequence PrintEntireReportWhenFinishedTesting.seq that I found on the NI website. I want to change the print font attribute. The dll doesn't include prototype information so I need information on the parameters for the SetPrintAttributeEx function. Specifically what number refers to the ATTR_PRINT_FONT_NAME attribute and what are acceptable values for the value of this parameter.
    Attachments:
    PrintEntireReportWhenFinishedTesting.seq ‏37 KB

    Wendell,
    I believe this question was also posted in the TestStand category. Since this is more of a TestStand question, it was seen and already answered. Please see Using cvirte.dll from teststand.
    Thanks!
    Shannon R
    Applications Engineer
    National Instruments

  • Debbugging MFC DLL with TestStand.

    I am in the process of evaluating TestStand and am very impressed with the tool. I created an MFC DLL with my existing C++ test code and have succesfully executed it through Teststand using the flexible prototype adapter. What seems to be missing is the ability to debug the DLL in Visual studio. I'm not sure if I need to have Visual Studio reference TestStand for DLL testing or visa versa. Please advise, as this is the last item I need to confirm prior to purchase. Is this a feature on version 2.0 ?? Thanks in advance.

    Mark-
    You can debug DLLs from TestStand that were created as debuggable DLLS in their original ADE by launching the TestStand Sequence Editor (\TestStand\Bin\SeqEdit.exe) from within your DLL's ADE. In your case you would run the SeqEdit.exe as an external process from within the Visual C++ development environment.
    Here is the description of how to do this from pg 12-12 in the TestStand User Manual that should already be installed on your computer under Start>>Programs>>National Instruments TestStand>>Online Help
    "To debug a DLL, create the DLL with debugging enabled in
    LabWindows/CVI or in another ADE. To debug DLLs, you must launch
    the sequence editor or run-time operator interface from LabWindows/CVI
    or the other ADE. In LabWindows/CVI, you use the Select
    External
    Process command in the Run menu of the Project window to identify the
    executable for the sequence editor or run-time operator interface. You then
    use the Run command to start the executable.
    If you select the Step Into command in TestStand while execution is
    currently suspended on a step that calls into a LabWindows/CVI DLL that
    you are debugging, LabWindows/CVI breaks at the first statement in the
    DLL function."
    Hope this helps!
    Regards,
    Richard McDonell
    National Instruments

  • How to pass csv data from file into DLL using TestStand

    Hi,
    We have data files which are of CSV format. Each row contains
    about 9 items of data, and have about 5 rows of this data (ie, 5
    test points) :
    eg
    TErrAdd1,UUT,UUT,STM1E,AU4/FR,PRBS23,BIT,10,60
    TErrAdd2,UUT,UUT,STM4O,AU3/UNFR,PRBS15,B1,20,60
    TErrAdd3,UUT,UUT,STM16O,AU4_16C/UNFR,PRBS9,BIT,7,60
    TErrAdd4,UUT,UUT,STM0E,AU3/UNFR,PRBS20,B2,5,60
    TErrAdd5,UUT,UUT,STM64O,AU4_4C/FR,PRBS11,B1,6,60
    What we want to do is to be able to directly pass each
    row of data to a C/C++ DLL. The DLL fn accepts this
    data as a vector of strings.
    eg.
    void DLLTestFn( vector const & configData )
    However, we can write a wrapper for the DLL as I don't
    think TestStand will know about vectors.
    We don't really want to have to hardcode individial references
    to each item of data in TestStand. Is this possible?
    Just read in a row from a data file, and sent it direct
    to the DLL?

    Hi Richardi,
    the principle is quite simple, however, you still need to use a programming language to make the initial file read.
    Once you've done this, you could have it as an array of strings, and pass this directly to a wrapper DLL, which would then pass the data into a string vector.
    Look up the examples\AccessingArrays\PassingArrayParametersToDll\AccessingArrays.seq
    to see how to do this without passing the sequence context.
    If you've read in the details into a container type structure already, then I've made an example which demonstrates this principle and what you'll need to pass it to a vector. (Similar principle can be used to fill in the container when you read the file in the first place.
    You cannot go directly to a vector, since TestStand doesn't understand them.
    Vector classes are difficult to export polymorphically from a DLL since the template class doesn't export, and needs specifically defining. This is what I'm assuming you're ultimately trying to do. (see ref :
    How to Export STL components inside and outside of a class
    I've used VIsual C++ 6 and TestStand 3.0
    Please let me know if this helps to answer your query.
    Thanks
    Sacha Emery
    National Instruments (UK)
    // it takes almost no time to rate an answer
    Attachments:
    for hannah vectors.zip ‏1619 KB

  • Problem calling more than one instance of a dll from TestStand

    Hi,
    I've posted this message in the LabWindows forum a few days ago and haven't gotten any answer. I have made a DLL with the evaluation version of LabWindows 7.1 to connect to a Telnet server and perform various commands. This DLL is used with TestStand 3.1 . In TestStand, I have to connect simultaneously to the same Telnet server twice to start an application with both of those connection, with different parameters. I use Threads in TestStand to call the DLL and everything seems to be fine on that side. I enter the DLL at the same time for both threads but it seems that the 1st thread waits until the 2nd thread is at the end of the function before he executes the InetTelnetOpen command to start the Telnet session. Is it normal that we can only have one Telnet connection at a time?
    To see that I've placed some time stamps in a log. For the first Thread, almost a minute passes by between the first 2 time stamps but in the 2nd thread it take less than a second.
    Yet, they both wait for eachother to exit the DLL as the time stamp at the end of the execution is the same.
    I really need some enlightenment here ;-)
    Louis
    Attachments:
    TelnetTest.txt ‏3 KB

    Tiwi,
    The blocking that InetTelnetRunScript does is probably there for a reason. That method is probably not safe for multiple threads to call into at the same time. There is likely another way to do what you are trying to do that can be done in parallel. Perhaps with lower-level telnet function calls. I recommend you post to the CVI forum asking if there is another way to do what you are trying to do from multiple threads in parallel. This does not sound like a teststand issue. If you are calling into your dll from multiple testand threads, then the code in your dll function is being executed in parallel. The cvi function you are calling however, might not be reentrant (reentrant means able to be called by multiple threads in parallel) so it is making one of your threads block until the other completes. I suspect there is a different way to do what you are trying to do that will not have this problem, but I think the changes that you will need to make will be in the dll and not on the teststand side. I recommend you post to the CVI group and explain what you are trying to accomplish and see if they have a solution for you.
    Hope this helps,
    -Doug
    P.S. Each process on the Windows operating system (of which teststand is one) can only load one copy of any particular dll at a time. Also, loading multiple copies is not something that would be likely to solve the problem you are running into. One possibility is to use the call executable step type and create an executable that does what your dll function does, but that is probably not the best solution and might still end up blocking at the same location. The best solution is probably to use an alternate method of accomplishing whatever you are trying to do with the telnet function you are calling that does not have the limitations of that function.

  • Ho to run LV-DLL in TestStand with bool-parameters?

    Hello,
    i´m using LabView 8.21 and Teststand 3.5. Currentlly i´m playing with the project-Explorer where i´m creating DLLs.
    The first and easiest step was to create a new VI with string-in and string-out.
    Then i added this vi to my project and created a DLL from it.
    This DLL is called in TestStand where the parameters are automatically detected and everything works perfect.
    But when i add an boolean-input and boolean-output und do exactly the same then Teststand says:
     "This function either does not have parameter-information in the DLL or uses types not recognised by teststand."
    The type of the boolean is "LVBOOLEAN" in the created header-file.
    What
    am i doing wrong? Why is this simple bool-value not working? If bool
    works not then i can never use the Labview-error-out-cluster inside a
    DLL?
    Or is there an easy trick to solve this?
    Thanks for your help

    Hi OnlyOne,
    I just verified your issue and figured out that a boolean value cannot be transfered to a LV dll, because the datatype representation of a boolean is different in LabVIEW than in C.
    The flexible Prototype adapter from TesStand can identify the functions of your LabVIEW dll when you use basic datatypes like scalars, pointer to scalars or C strings. That's the reason why it works in your "String dll".
    When one uses LabVIEW specific datatypes there will no typelibrary provided and it's essential to define the prototype manual in TestStand. I found a link that provides some more information to that:
    http://digital.ni.com/public.nsf/websearch/DBCE27265FFB554986256C9400026FE8?OpenDocument
    One possibillity to transfer boolean values simply to a LV dll would be to use a numeric value, for example an integer and use a comparison like "!0" in the LV dll to determine if the status means "true" or "false".
    Hope that helps to come along with your application,
    regards,
    Nikolai

  • How do I pass a custom data type to a dll in TestStand?

    I need to add a new feature / function to an existing TestStand program.  The original program uses a custom data type for the LabVIEW VISA (serial com) reference, as shown below.  I want to use the StationGlobals.VISA_Ref in my call to the dll.
    The VI prototype is shown below.  The VISA Ref In is a basic VISA reference control (serial comm) from LabVIEW.  Nothing special.
    I am stuck at trying to figure out how to configure the VISA Ref In parameter...  I've searched this forum and the only posts which seem close to what I am attempting to do did not have any responses... I hope to be "luckier".. 
    Attachments:
    LVIOctrl.PNG ‏23 KB
    VIprototype.PNG ‏20 KB
    ConfigParm.PNG ‏37 KB

    What you are describing is similar to this, right?  http://digital.ni.com/public.nsf/allkb/22BF02003B4588808625717F003ECD67
    I tried something similar to what you described.... unfortunately, TestStand is holding on to the serial port and has not let go yet...  Which causes a run-time error within the LabVIEW code (dll) because the resource it is trying to use (COM port) is not available... 
    I will check the code and see whether they use the serial port after it gets to the new feature...  Otherwise, I may close the port, use it within LabVIEW (dll), close it and then re-open within TestStand...  That's why I wanted to pass the reference directly...  Although, the way you describe it, it may be possible to pass that same reference indirectly and get the dll to work without having to play with closing / opening references.  I'll explore that tomorrow.
    Thanks.

  • Debugging Labwindows dll in teststand with CVI 9.1.1

    Is there a known problem when debugging Labwindows DLL used as Teststand Code module ( using the Labwindows CVI Adapter)?
    My setup includes to powersupplies with IVI instrument drivers ( Agilent 6032A and and E3634 A) a a few other instruments with non-IVI instruments drivers. When start CVI, load the dll project and then start the Teststand Sequence editor as program to be debugged an then step into the C-Code it looks like there is process that watches both powersupplies and tries to reset them again if I access them from my C code through the instrument driver. There is no such effect with the non-IVI instruments and also if I run the code outside the debugger there is no such effect.
    Any Ideas whats going wrong here ?
    Solved!
    Go to Solution.

    some more information. I#ve updated now to CVI 2010 and the effect still exists. To demonstrate it I've attached a NI SPY log. The 6032A lives at GPIB ID 3 the E3634 at GPIB ID 5. I'am running the following code:
    Fmt(resource_id,"GPIB::%d::INSTR",addr_PS_P24V);
    tsErrChk(status = hp6xxxa_init (resource_id, VI_ON, VI_ON, 2, &Instr_Handle_PS_P24V));
    // Export Instrument handle for PS_P24V
    tsErrChk (TS_PropertySetValNumber (testData->seqContextCVI, &errorInfo,
    "FileGlobals.Instr_Handle_PS_P24V", 0x1,
    Instr_Handle_PS_P24V));
    //set limit voltage and current
    // status = hp6xxxa_603xA_soft_limits (Instr_Handle_PS_P24V, 30, 0.5);
    tsErrChk (status = hp6xxxa_603xA_fold (Instr_Handle_PS_P24V, 0));
    //set voltage and current depending on device A/AP 10A B/C 11.5 A
    if ( is_ALA_B_device( testData->seqContextCVI) || is_ALA_C_device( testData->seqContextCVI) )
    tsErrChk (status = hp6xxxa_volt_curr (Instr_Handle_PS_P24V, 26.0, 11.5, 1));
    else
    tsErrChk (status = hp6xxxa_volt_curr (Instr_Handle_PS_P24V, 26.0, 10.0, 1));
    tsErrChk (status = hp6xxxa_delay (Instr_Handle_PS_P24V, 0.500, 1));
    Delay(.2);
    //output off
    tsErrChk (status = hp6xxxa_output_onoff (Instr_Handle_PS_P24V, 0, 1));
    Delay(.2);
    [... later for the E3634]
    // Get GPIB-Adress of PS_P3V3
    tsErrChk(TS_PropertyExists(testData->seqContextCVI, &errorInfo, "FileGlobals.GPIB_ADDR_PS_P3V3", 0, &propertyExists));
    if (propertyExists)
    tsErrChk (TS_PropertyGetValNumber(testData->seqContextCVI, &errorInfo,
    "FileGlobals.GPIB_ADDR_PS_P3V3",
    0, &GPIB_ADDR_PS_P3V3));
    addr_PS_P3V3 = GPIB_ADDR_PS_P3V3;
    #ifndef NO3V3 // NO 3.3V programmable source on TK2
    // Initialize PS_P3V3
    Fmt(resource_id,"GPIB::%d::INSTR",addr_PS_P3V3);
    tsErrChk(hpe363xa_init (resource_id, VI_TRUE, VI_TRUE, &Instr_Handle_PS_P3V3));
    // Export Instrument handle for PS_P3V3
    tsErrChk (TS_PropertySetValNumber (testData->seqContextCVI, &errorInfo,
    "FileGlobals.Instr_Handle_PS_P3V3", 0x1,
    Instr_Handle_PS_P3V3));
    hpe363xa_ConfigureOutputRange (Instr_Handle_PS_P3V3, "",
    HPE363XA_VAL_RANGE_VOLTAGE, 5);
    hpe363xa_ConfigureVoltageLevel (Instr_Handle_PS_P3V3, "", 3.3);
    // Output off
    hpe363xa_ConfigureOutputEnabled (Instr_Handle_PS_P3V3, "", VI_FALSE);
    hpe363xa_ConfigureCurrentLimit (Instr_Handle_PS_P3V3, "",
    HPE363XA_VAL_CURRENT_REGULATE, 0.5);
    hpe363xa_ConfigureOVP (Instr_Handle_PS_P3V3, "", VI_TRUE, 4);
    #endif
    #ifdef TK3 // use E3640 powersupply for TK3
    Fmt(resource_id,"GPIB::%d::INSTR",addr_PS_P3V3);
    tsErrChk(hpe364xa_init (resource_id, VI_TRUE, VI_TRUE, &Instr_Handle_PS_P3V3));
    // Export Instrument handle for PS_P3V3
    tsErrChk (TS_PropertySetValNumber (testData->seqContextCVI, &errorInfo,
    "FileGlobals.Instr_Handle_PS_P3V3", 0x1,
    Instr_Handle_PS_P3V3));
    hpe364xa_ConfigureOutputRange (Instr_Handle_PS_P3V3, "1",
    HPE364XA_VAL_RANGE_VOLTAGE, 5);
    hpe364xa_ConfigureVoltageLevel (Instr_Handle_PS_P3V3, "1", 3.3);
    hpe364xa_ConfigureCurrentLimit (Instr_Handle_PS_P3V3, "1",
    HPE364XA_VAL_CURRENT_REGULATE, 0.5);
    hpe364xa_ConfigureOVP (Instr_Handle_PS_P3V3, "1", VI_TRUE, 4);
    // Output on
    hpe364xa_ConfigureOutputEnabled (Instr_Handle_PS_P3V3, "1", VI_TRUE);
    #endif
    If you look into the Spy Log you will see at #241 the first hit of that strange process, which beginns with a viOpenDefaultRM
    and ends with a viClose at #252
    after issuing an *IDN?, which fails because the 6032A doesn't support *IDN?. Then the first driver call ( init function) can be identified.
    later on , when the code goes to the E3642 using ID5 at #1142 in SPY log you will see that the strange process will finally send a *RST if the *IDN? succeeds.

  • Pass error cluster from labview dll to teststand

    Hello,
    I just want to pass an error cluster from a dll compiled in LV7.1 to TestStand 3.1. I never receive the contents of the LV error cluster in TS. I compiled my function with standard calling convention option, this should work. In my VI I generate only an error and pass to error output.
    LV Settings:
     TS settings:
    regards
    MB

    MB,
    please follow the info in this KB:
    http://digital.ni.com/public.nsf/allkb/22BF02003B4588808625717F003ECD67?OpenDocument
    Please note that using "By Value" will never return any values to TestStand!
    You cannot use the default error-container in TestStand to receive data from the LV error cluster if you compile the VI into a LV DLL.
    So either you choose to follow the KB or you split up the error cluster in your LV VIs to return error.occurred (boolean), error.code (numeric i32) and error.msg (LV String) .
    hope this helps,
    Norbert
    CEO: What exactly is stopping us from doing this?
    Expert: Geometry
    Marketing Manager: Just ignore it.

  • Calling a DLL in TestStand by reference

    All,
    I have developed a DLL that control's a USB based power supply. The dll call works from TestStand 4.1 most of the time. What I believe is happening is that each time I call the dll in my Main sequence file AS WELL AS other sequence files, that multiple instances of the dll are loaded.
    Part of the init of the power supply is to pass back a SESSION number, which is used in subsequent calls to the dll. I store it as a Global variable in TestStand and pass it around to what ever sequence needs it.
    How can I load the DLL at the start of the sequence and PASS a reference (Handle) to all additional calls to the dll?
    thanks in advance
    Carmine
    Solved!
    Go to Solution.

    I checked and found that I had a release and debug version that were both beig called. That is now corrected. (Thanks)
    Program still has the problem.
    The "proper dll" is called from my first sequence, but called again in other sequences that are in separate files. As you suggested I looked at the load and unload options>    I am not seeing an option that keeps the dll from unloading when the sub sequence file finishes and exits.
    Program Architecture is as follows:
    "Main File.seq" calls a "Child1.seq" to init a power supply and passes back a HANDLE, Now  "Main File.seq" AND "Child2.seq" make calls to the Power Supply using the HANDLE.
    Any additional help is welcome.
    Thanks in advance

  • Passing struct to DLL using TestStand

    I would like to pass structures to the function call in the DLL. Does Test stand supports passing structured.
    I have a function prototype like this
    LONG _stdcall ReadData(HANDLE hInstance, pDataStruct Trans);
    #pragma pack(push, 1)
    typedef struct _DataStruct {
    BYTE Type;
    BYTE DevAddr;
    WORD wMemoryAddr;
    WORD wCount;
    BYTE Data[256];
    } DataStruct , *pDataStruct ;
    #pragma pack(pop)
    I would like to display the Data filed after the function call.
    remaining parameters to the structure are inputs.
    Please point me to any tutorial on TestStand that can help me or Give me a detailed instructions on how to configure it.
    Thanks in advance.
    Lak

    There is a "StructPassing" example in the TestStand/examples folder. It shows how you can pass the struct to DLL function. Additionally, you can access the struct using TestStand API.
    Yevgeny

  • How sharing a COM object with severeal test dlls in teststand

    I have several tests (dlls) accessing a DAQ board (not VI compliant) thanks to a COM object. I would like to keep one instance of this object, passing its reference to each test dll, instead of creating one in each test. How can I do that with TestStand?

    You can do one of two things to store a reference to the COM object in the context of TestStand so that you can pass it to successive steps in order for them to all use the same object instance.
    First, if you create the object in TestStand with an ActiveX Automation Adapter step, the method call to instantiate the object should return a reference to the object. If you designate an activex reference type local variable as the property to receive the reference during the creation operation, you should be able to pass this into methods that use IDispatch* parameters, or you can use the TestStand API to access the TestStand variable instead.
    The second scenario is very similar, in that if you don't create the object in TestStand but inside of a dll instea
    d, you can simply pass the parameter back from a function into a TestStand activex reference property variable or use the TestStand API inside of the dll to set the value of an activex reference property to the IDispatch of the object.
    To better understand how to use the ActiveX Automation Adapter and ActiveX Reference Variable Types, look at Chapter 13 of the TestStand User Manual under the section entitled "ActiveX Automation Adapter". I have also attached an example to this post that uses the ActiveX Automation Adapter and ActiveX reference datatype in a sequence that writes data to a Microsoft Excel spreadsheet and generates a chart from the data.
    Jason F.
    Applications Engineer
    National Instruments
    www.ni.com/ask
    Attachments:
    Write_Table_to_XL_and_Create_Chart.seq ‏53 KB

Maybe you are looking for

  • How to find out if a role is deleted

    Hi security experts, We are trying to find out the way to identify the role(s) that have been deleted within a certain time interval. In which table is this information stored? Actually we are interested in getting to know the roles without profile a

  • Silent mode switcher doesn't work!

    Hi, I have an iPhone 3Gs covered by warranty and I would like to know if Apple changes my iPhone if my Silent mode swithcer doesn't work?? (if my English isn't very good is because I'm Italian xD)

  • Setting a default font size for imail

    When I send an email people say the font is TINY... how do I fix this?

  • DAC Connectivity Error

    Hi Experts, Please help, I'm very new to DAC. I was trying to create a new connection in DAC, but it is throwing me a error message (Please see below), Error while creating repository table, [IBM][CLI Driver][DB2/AIX64] SQL0601N the name of the objec

  • Download an image with JS?

    I´m trying to download an image from an URL with Javascript using socket. My first problem was separating the header from the body. I do it by reading line by line and if the line starts with "\n" then it seams to be the body. A problem with this is