Char Pointer from C++ DLL

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mdonders
    New Member
    • Oct 2009
    • 5

    Char Pointer from C++ DLL

    I recently converted my application into C# as VS2008 does not support new Data Sources (?!), but now I am stuck on one command from the old DLL.

    Here is the old function declaration and command that worked in C++:
    Code:
     typedef short(*pfunc2)(short address, LPSTR cmd, short irqnum);
     pfunc2 pfSendAT6400Block	=	(pfunc2)GetProcAddress(hndl, "SendAT6400Block");
    
    char *testCommands[258] = {"A100:V50:D254000:GO1:"}; //Pointer to a null-terminated string 
    SetTimeout(10000);					
     SendAT6400Block(768, *testCommands, 0);
    I definitely have the DLL loaded correctly in C# as the other commands work, but I have a feeling my syntax with sending the commands, which would be the LPSTR cmd delcaration. My C# code snippets are below.
    Code:
    [DllImport("C:\\WINDOWS\\system32\\nt6400.dll", CharSet = CharSet.Auto)]
    public static extern short SendAT6400Block(short address, [MarshalAs(UnmanagedType.LPStr)] string cmd, short irqnum);
    
    string commandSTR = "A100:V50:D254000:G01:";
    NT6400.SetTimeout(2000);
    int SendBlockReturn = NT6400.SendAT6400Block(768, commandSTR, 0);
    So now my SendAT6400Block is not working in C# when it was working in my old C++ code. Could anyone provide any insight or do you need some more information?

    Your help, as always, is greatly appreciated.
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    #2
    Have you tried ensuring that your strings end in a null byte? I don't think .NET strings specifically do.

    Comment

    • mdonders
      New Member
      • Oct 2009
      • 5

      #3
      Originally posted by Plater
      Have you tried ensuring that your strings end in a null byte? I don't think .NET strings specifically do.
      So would I just add a \0 to the end of my string to null-terminate it?

      If its that easy that would be awesome.

      Thanks in advance.

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        Give it a try? I'm not sure it's the solution, but it would make a simple fix if it were

        Comment

        • mdonders
          New Member
          • Oct 2009
          • 5

          #5
          Well the function returned a value of 22 (bytes sent to the controller), but I still got no motion from the controller.

          BTW when I send the command its supposed to make the arm attached to the controller move a certain distance with specified acceleration and speed.

          My thought is that the command was actually sent and received by the controller (all 22 bytes of it), but the pointer to the null terminated string is not being sent.

          Here is the code as of right now:
          Code:
          string commandSTR = "A100:V50:D254000:G01:\0";
          //IntPtr commandPTR = Marshal.StringToHGlobalAuto(commandSTR);
          
          NT6400.SetTimeout(2000);
          int SendBlockReturn = NT6400.SendAT6400Block(768, commandSTR, 0);
          From reading other stuff online I was also looking at trying an IntPtr to send the string (as the commented line above indicates). Not sure if my code was correct or not, but the string is definitely null terminated and I am not seeing a response.

          Anyone have any insight or idea of what might be happening?

          Comment

          • Plater
            Recognized Expert Expert
            • Apr 2007
            • 7872

            #6
            Is there anyway you can see what the arm controller is actually getting?

            Comment

            • mdonders
              New Member
              • Oct 2009
              • 5

              #7
              The return value of the function is the number of bytes received from the product. I put that value into a messageBox and it displays "22 bytes received" so I think it MAY be working although I am still getting no movement.

              Here is the exact text from the function:
              "cmd" - Pointer to a null-terminated string that contains on or more commands. Commands must be separateed with a carriage return of colon. The buffer that cmd points to should be 258 bytes in size.

              My next attempt (if necessary) is this:
              Code:
              byte[] byteArray;
              byteArray = new byte[257];
              
              string commandSTR = "A100:V50:D254000:G01:\0";
              
              byteArray = StrToByteArray(commandSTR);
              
              NT6400.SetTimeout(2000);
              int SendBlockReturn = NT6400.SendAT6400Block(768, byteArray, 0);
              Thanks again for your help.

              Comment

              • Plater
                Recognized Expert Expert
                • Apr 2007
                • 7872

                #8
                Hmm, maybe it expects 258bytes?
                Try creating your command to be 258bytes long(for safety sake, make all the additional bytes AFTER your command be the \0)

                Comment

                • vkbishnoi
                  New Member
                  • Oct 2009
                  • 6

                  #9
                  try this

                  [DllImport("C:\\ WINDOWS\\system 32\\nt6400.dll" , CharSet = CharSet.Ansi)]
                  public static extern short SendAT6400Block (short address, string cmd, short irqnum);

                  Comment

                  • mdonders
                    New Member
                    • Oct 2009
                    • 5

                    #10
                    Originally posted by vkbishnoi
                    try this

                    [DllImport("C:\\ WINDOWS\\system 32\\nt6400.dll" , CharSet = CharSet.Ansi)]
                    public static extern short SendAT6400Block (short address, string cmd, short irqnum);
                    Okay will give that a shot today.

                    Just one question relating to it though -- why doesn't Auto just automatically use Ansi then?

                    Comment

                    • Plater
                      Recognized Expert Expert
                      • Apr 2007
                      • 7872

                      #11
                      Originally posted by mdonders
                      Okay will give that a shot today.

                      Just one question relating to it though -- why doesn't Auto just automatically use Ansi then?
                      Probably defaults to unicode (as it should)

                      Comment

                      • vkbishnoi
                        New Member
                        • Oct 2009
                        • 6

                        #12
                        Originally posted by vkbishnoi
                        try this
                        [code=c#]
                        [DllImport("C:\\ WINDOWS\\system 32\\nt6400.dll" , CharSet = CharSet.Ansi)]
                        public static extern short SendAT6400Block (short address, string cmd, short irqnum);[/code]
                        I tried creating a VC++/MFC dll with a function signature

                        short SendAT6400Block (short a, LPSTR command, short b);

                        and using the above pinvoke signature i was able to pass the string successfully to this DLL.

                        Also i tried these signatures in the VC++/MFC dll

                        short SendAT6400Block (short a, char* command, short b);
                        short SendAT6400Block (short a, char command[258], short b);

                        and all of them are working fine. Please note that this VC++/MFC dll is developed using VS2005 as i do not have VC6. In case my previous suggestion is not working then can you share the C++ side function signature.

                        Comment

                        Working...