structure of result string from ptpcam.dll - DSLR Hack development - CHDK Forum

structure of result string from ptpcam.dll

  • 9 Replies
  • 3815 Views
structure of result string from ptpcam.dll
« on: 04 / February / 2013, 20:51:36 »
Advertisements
I am using Visual Studio Express 2012, completing a template for what is called an ASCOM (www.ascom-standards.org) camera driver, that should allow telescope observatory control software to communicate with any CHDK equiped camera.  I am trying to use the ptpcam gui as a model and ptpcam.dll as the interface.

I am able to control the camera from my C# application via ptpcam.dll, which works great.

I am unable to read the result back from the ptpcam.dll.  I am able to see the pointer, but am unable to decipher the result:  an array?   

The dll defines it is a null terminated string, but looks like a 2x4 array and I am stuck trying to decode it. 

I have started with trying to read the temperature.  Snippet below is what I have used to try and read the result, but I am stuck here.   

Appreciate advice & suggestions.



   if (ptpcam.SendCommand("lua get_temperature(1)") == 0) { Console.WriteLine("error getting temp "); } // 0 returns optical, 1 returns CCD, and 2 returns battery temp
                 
                    char StdOut_crs = ptpcam.GetStdOut();

                    char[] StdOut = new char[10];

                    unsafe
                    {
                        char* p = &StdOut_crs;

                        for (int i1 = 0; i1 < 10; i1++)
                        {


                            {

                                StdOut[i1] = *p;
                                p++;

                                int value = Convert.ToInt32(StdOut);
                                // Convert the decimal value to a hexadecimal value in string form.
                                string hexOutput = String.Format("{0:X}", value);
                                Console.WriteLine("Hexadecimal value of pointer {0} is {1} and decimal {2}", StdOut_crs, hexOutput, value);

                                value = Convert.ToInt32(*p);
                                // Convert the decimal value to a hexadecimal value in string form.
                                hexOutput = String.Format("{0:X}", value);
                                Console.WriteLine("Hexadecimal value stored at pointer location {0} is {1} and decimal {2}", *p, hexOutput, value);


*

Offline rudi

  • ***
  • 126
  • A590IS_101B, SX260HS_100B
Re: structure of result string from ptpcam.dll
« Reply #1 on: 05 / February / 2013, 03:23:03 »
Hi begin_astro,

ptpcam.dll return a pointer of char. The puffer is allocated by dll. Look at here.

It should be enough:  char* p = ptpcam.GetStdOut();

For simple test, you can use ptpcam.GetDllVersion() -> return "0.2" as pchar.

Re: structure of result string from ptpcam.dll
« Reply #2 on: 06 / February / 2013, 00:41:27 »
rudi - I think that helped.  I did some cleanup but I am getting what looks like asian characters back for a string instead of "0.2" for the version...GetStdOut is giving me similar answer...


        if (ptpcam.SendCommand("lua get_temperature(1)") == 0) { Console.WriteLine("error getting temp "); } // 0 returns optical, 1 returns CCD, and 2 returns battery temp

                    unsafe
                    {
                        char* p = ptpcam.GetStdOut();
                        char* p_dll = ptpcam.GetDllVersion();
                        string crs_out;
                        string dll_out;
                        dll_out = new String(p_dll);
                        crs_out = new String(p);
                    }

*

Offline rudi

  • ***
  • 126
  • A590IS_101B, SX260HS_100B
Re: structure of result string from ptpcam.dll
« Reply #3 on: 06 / February / 2013, 06:33:09 »
This looks like a charset missmatch between ptpcam.dll and C#. The library use an ansi charset (one byte per char). C# use per default unicode (two bytes per char). Check your dll import section for charset definition.

related links:
https://forums.embarcadero.com/thread.jspa?threadID=71860
http://social.msdn.microsoft.com/Forums/en/clr/thread/3a9a10de-b212-419a-b1dc-f4846c57f7ed


Re: structure of result string from ptpcam.dll
« Reply #4 on: 06 / February / 2013, 21:31:03 »
Looks like that did the trick.

Posted here in case it helps someone else.

[DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern char* GetDllVersion();
       
[DllImport("ptpcam.dll",CharSet = CharSet.Ansi)]
        public static extern char* GetStdOut();
       
unsafe
                    {
                        char* p = ptpcam.GetStdOut();
                        char* p_dll = ptpcam.GetDllVersion();
                        string crs_out, dll_out;
                        dll_out = Marshal.PtrToStringAnsi((IntPtr) (char*) p_dll);
                        crs_out = Marshal.PtrToStringAnsi((IntPtr) (char*) p);
                    }

dll_out = 2.0!

Now I just have to learn how to parse the returned string.

Vielen Dank!

Re: structure of result string from ptpcam.dll
« Reply #5 on: 10 / February / 2013, 09:32:31 »
Rudi - 

I was able to read the dll version properly, but only the first line of the GetStdOut() result.  This is probably due to the marshal.ptrtostringansi truncating at first null, so that I am always seeing "script:34" and nothing more.

Any suggestions on how to get the complete return "array"?

Thank you, again.


*

Offline rudi

  • ***
  • 126
  • A590IS_101B, SX260HS_100B
Re: structure of result string from ptpcam.dll
« Reply #6 on: 12 / February / 2013, 11:34:09 »
Now, I installed a c# version 2010, create a c# windows-Forms Application with a Button and RichTextBox.

add on Program.cs:
Code: [Select]
namespace WindowsFormsApplication1
{
    public class ptpcam
    {
        [DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern int CreateConsole(int show, int bus, int dev);
        [DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern int CloseConsole();
        [DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern int IsCamConnected();
        [DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern int IsConsoleReady();
        [DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern string GetDllVersion();
        [DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern string GetStdErr();
        [DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern string GetStdOut();
        [DllImport("ptpcam.dll", CharSet = CharSet.Ansi)]
        public static extern int SendCommand(string stdin);
    }

    static class Program
    {
       ...
code for Button1 in Form1.cs:
Code: [Select]
        private void button1_Click(object sender, EventArgs e)
        {
            bool err = false;
            if (ptpcam.CreateConsole(0, 0, 0) == 1)
            {
                richTextBox1.AppendText("> ptpcam open\n");
                int timeout = 30; //equal ~3 seconds
                while (ptpcam.IsCamConnected() != 1 && timeout > 0) { timeout--; Thread.Sleep(100); }
                err = (timeout == 0);

                if (!err)
                {
                    while (ptpcam.IsConsoleReady() != 1) { Thread.Sleep(100); }
                    string cmd = "luar get_buildinfo()";
                    int r_send = ptpcam.SendCommand(cmd);
                    richTextBox1.AppendText(string.Format("send '{0}'; result = {1}\n", cmd, r_send));

                    if (r_send == 1)
                    {
                        richTextBox1.AppendText("--- receive begin ---\n");
                        while (ptpcam.IsConsoleReady() != 1) { Thread.Sleep(100); }
                        string r_dll = ptpcam.GetStdOut();
                        richTextBox1.AppendText(r_dll + '\n');
                        richTextBox1.AppendText("--- receive end ---\n");
                    }
                    else richTextBox1.AppendText("!!! ptpcam: send error\n");
                }
                else richTextBox1.AppendText("!!! ptpcam: camera connection timeout\n");

                ptpcam.CloseConsole();
                richTextBox1.AppendText("> ptpcam closed\n");
            }
            else richTextBox1.AppendText("!!! ptpcam: open error\n");
        }
output on textbox:
> ptpcam open
send 'luar get_buildinfo()'; result = 1
--- receive begin ---
script:1
1:ret:'platform   sx260hs
build_date   Feb 11 2013
build_number   1.2.0
build_time   05:15:58
version   CHDK_DE
platsub   100b
build_revision   2567
platformid   12868
os   dryos
'
--- receive end ---
> ptpcam closed


That is the mainconcept of using ptpcam.exe over ptpcam.dll.

Re: structure of result string from ptpcam.dll
« Reply #7 on: 13 / February / 2013, 23:19:20 »
Rudi - thank you for this.  Embarrassing, but I am stuck setting up the threading for the thread.sleep() commands


Re: structure of result string from ptpcam.dll
« Reply #8 on: 17 / February / 2013, 08:44:47 »
Rudi,

I was able to  single-step through your example and also to get my code to work with the following changes:

1)  keep the dll definition of GetStdOut() as char-pointer, and marshal the result using the Marshal.ptrtostring...
2)  change the lua command to a "luar get_temperature(1)"  or "luar get_buildinfo()".   The "r" was something I missed...

Right now I am parsing the result with something like:


                   string luacmd = "luar get_temperature(1)";
                   
                    if (ptpcam.SendCommand(luacmd) == 0) { Console.WriteLine("error with " + luacmd); } // 0 returns optical, 1 returns CCD, and 2 returns battery temp
                    unsafe
                    {
                   
                        char* p = ptpcam.GetStdOut();
                        crs_out = Marshal.PtrToStringAnsi((IntPtr)(char*)p);
                        int stdoutlen = crs_out.Length;
                        int pos1, pos2;
                        string res_typ;

                        if (crs_out.IndexOf("'", 0) > 0)
                        {
                            pos1 = crs_out.IndexOf("'", 0 );// complex text
                            pos2 = crs_out.IndexOf("'", pos1 );// complex text
                            parsed_out = crs_out.Substring(pos1, pos2 - pos1);
                            res_typ = "complex text";
                        }
                        else if (crs_out.IndexOf("true", 0) > 0) { parsed_out = "true"; res_typ = "bool"; }
                        else if (crs_out.IndexOf("false", 0) > 0) { parsed_out = "false"; res_typ = "bool"; }
                        else
                        {
                            int respos = crs_out.IndexOf(":ret:", 0) + 5;
                            stdoutlen = crs_out.IndexOf("(", respos);
                            parsed_out = crs_out.Substring(respos, stdoutlen - respos);
                            res_typ = "int";
                        }
 

Re: structure of result string from ptpcam.dll
« Reply #9 on: 17 / February / 2013, 12:59:11 »
Also, for some reason, Visual Studio Express 2012 prefers this syntax:

        while ( ptpcam.IsConsoleReady() == 0) { System.Threading.Thread.Sleep(300); }

Runs perfectly.  Thanks for your great tool set and support.

 

Related Topics