无法将字符串从 C 传输到 Ada

Can't transfer string from C to Ada

我正在尝试将字符串从 C 例程传输到 Ada 应用程序。我没有从 NI 设备读取,而是在 C 文件例程中硬编码了一个字符串。该字符串确实会传输,但还有其他非字符。字符串是 HELLO.

BUFFER = UH~I?H~C?^P?E?HELL?E?O?

C 程序是:


#include "gpib_intf.h"

#define MAX_SIZE 350

static ViStatus status, StatusSession;
static ViSession inst, defaultRM;
static char stringinput[256];
static ViUInt32 rcount, retCount;
static ViUInt32 BytesToWrite;
static unsigned char buffer[MAX_SIZE];

void setupDefaultRM()
{
   status = viOpenDefaultRM (&defaultRM);
   if (status < VI_SUCCESS)
      {
         printf("Could not open a session to the VISA Resource Manager!\n");
         exit (EXIT_FAILURE);
      }

   status = viOpen (defaultRM, "GPIB0::1::INSTR", VI_NULL, VI_NULL, &inst);
   if (status < VI_SUCCESS)
      {
         printf("Could not open a session to the GPIB Device!\n");
         exit (EXIT_FAILURE);
      }
}

void writeVI(char* stringinput)
{
   BytesToWrite = (ViUInt32)strlen(stringinput);
   status = viWrite (inst, (ViBuf)stringinput, BytesToWrite, &rcount);
}

void readVI()
{
   /*memset(buffer, 0, sizeof(buffer));*/
   const unsigned char version[5] = "HELLO";
   printf("\n");
   printf("version = %s\n", version);

   /*
   status = viRead (inst, buffer, MAX_SIZE, &retCount);
   if (status < VI_SUCCESS)
   {
      printf ("Error reading a response from the device.\n");
      }
   */
   /*return version;*/
}

读取它的 Ada 代码是:

   -------------------------------------------------------------------------
   -- READVI
   --
   -- read from GPIB device
   --
   function READGPIB return STRING is
      
      function READVI return STRING is
      version : char_array(size_t);
      pragma Import (C, version, "readVI");
         
      begin
         --return "     0";
         return To_Ada(version, Trim_Nul => True);
      end;

   begin
      --Text_IO.Put_Line(READVI);
      return READVI;
   end READGPIB;

您发布的 C 代码版本看起来像是来自早期开发阶段。如果这就是你实际使用的东西,那么你看到任何带有 HELLO 的东西都是一个奇迹,如果除了 C 端的 readVIvoid 之外没有其他原因 function,它对应一个Ada过程,而Ada方面认为它是一个char_array (size_t),不管是什么意思(size_t是一个类型,不是数字)。

C码,你要

char *readVI();

而在 Ada 端相应的声明是

function Read_VI return Interfaces.C.Strings.chars_ptr
with
  Import,
  Convention => C,
  External_Name => "readVI";

加起来,C端可能是

#include <string.h>
static char buffer[128];

char *readVI()
{
  strcpy(buffer, "Hello!");
  return buffer;
}

和艾达一方

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C.Strings;

procedure Joseph is
   function Read_VI return Interfaces.C.Strings.chars_ptr
   with
     Import,
     Convention => C,
     External_Name => "readVI";
begin
   Put_Line ("received '"
               & Interfaces.C.Strings.Value (Read_VI)
               & "'");
end Joseph;

我根据 Simon 的建议找到了我的问题。

C代码

/*
 *  Read from a GPIB device
*/
unsigned char* readVI()
{
   status = viRead (inst, buffer, MAX_SIZE, &retCount);
   /* If successful read */
   if (status == VI_SUCCESS)
   {
      /* copy data into return buffer */
      strcpy(buff, buffer);
   }
   return buff;
}

艾达代码

       -------------------------------------------------------------------------
   -- READVI
   --
   -- read from GPIB device
   --
   procedure READGPIB is
      
      function READVI return Interfaces.C.Strings.chars_ptr
        with
          Import,
          Convention => C,
          External_Name =>"readVI";
      
   begin
     declare
        Str : STRING := Interfaces.C.Strings.Value (READVI);
     begin
        for I in MSG3235_TYPE'Range loop
           GLOBALS.BUFFER(I) := Str(I);
           exit when Str (I) = ASCII.CR or Str (I) = ASCII.LF or Str (I) = ASCII.SEMICOLON;
         end loop;
     end;
  end READGPIB;